209 prev next chunks index CyanogenMod/android_packages_apps_Trebuchet_8f73d7032e557c6f01a9954a2ec0f386987946e4_src/com/android/launcher3/Launcher.java {strict: [[bj]], subset: [[bj]]}
line based (standard git) jfstmerge spork
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.SuppressLint;                                                                  
  26 import android.annotation.TargetApi;                                                                     
  27 import android.app.Activity;                                                                             
  28 import android.app.ActivityManager;                                                                      
  29 import android.app.ActivityOptions;                                                                      
  30 import android.app.AlertDialog;                                                                          
  31 import android.app.SearchManager;                                                                        
  32 import android.appwidget.AppWidgetHostView;                                                              
  33 import android.appwidget.AppWidgetManager;                                                               
  34 import android.appwidget.AppWidgetProviderInfo;                                                          
  35 import android.content.ActivityNotFoundException;                                                        
  36 import android.content.BroadcastReceiver;                                                                
  37 import android.content.ComponentCallbacks2;                                                              
  38 import android.content.ComponentName;                                                                    
  39 import android.content.ContentResolver;                                                                  
  40 import android.content.Context;                                                                          
  41 import android.content.DialogInterface;                                                                  
  42 import android.content.Intent;                                                                           
  43 import android.content.IntentFilter;                                                                     
  44 import android.content.IntentSender;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.database.ContentObserver;                                                                 
  52 import android.database.sqlite.SQLiteDatabase;                                                           
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.PorterDuff;                                                                      
  57 import android.graphics.Rect;                                                                            
  58 import android.graphics.drawable.ColorDrawable;                                                          
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.text.Selection;                                                                           
  70 import android.text.SpannableStringBuilder;                                                              
  71 import android.text.TextUtils;                                                                           
  72 import android.text.method.TextKeyListener;                                                              
  73 import android.util.Log;                                                                                 
  74 import android.view.Display;                                                                             
  75 import android.view.Gravity;                                                                             
  76 import android.view.HapticFeedbackConstants;                                                             
  77 import android.view.KeyEvent;                                                                            
  78 import android.view.LayoutInflater;                                                                      
  79 import android.view.Menu;                                                                                
  80 import android.view.MotionEvent;                                                                         
  81 import android.view.Surface;                                                                             
  82 import android.view.View;                                                                                
  83 import android.view.View.OnClickListener;                                                                
  84 import android.view.View.OnLongClickListener;                                                            
  85 import android.view.ViewGroup;                                                                           
  86 import android.view.ViewStub;                                                                            
  87 import android.view.ViewTreeObserver;                                                                    
  88 import android.view.Window;                                                                              
  89 import android.view.WindowManager;                                                                       
  90 import android.view.accessibility.AccessibilityEvent;                                                    
  91 import android.view.inputmethod.InputMethodManager;                                                      
  92 import android.widget.Advanceable;                                                                       
  93 import android.widget.FrameLayout;                                                                       
  94 import android.widget.ImageView;                                                                         
  95 import android.widget.TextView;                                                                          
  96 import android.widget.Toast;                                                                             
  97                                                                                                          
  98 import com.android.launcher3.DropTarget.DragObject;                                                      
  99 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 100 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;                                
 101 import com.android.launcher3.allapps.AllAppsContainerView;                                               
 102 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 103 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 104 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 105 import com.android.launcher3.compat.UserHandleCompat;                                                    
 106 import com.android.launcher3.compat.UserManagerCompat;                                                   
 107 import com.android.launcher3.model.WidgetsModel;                                                         
 108 import com.android.launcher3.util.LongArrayMap;                                                          
 109 import com.android.launcher3.util.Thunk;                                                                 
 110 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 111 import com.android.launcher3.widget.WidgetHostViewLoader;                                                
 112 import com.android.launcher3.widget.WidgetsContainerView;                                                
 113                                                                                                          
 114 import java.io.DataInputStream;                                                                          
 115 import java.io.DataOutputStream;                                                                         
 116 import java.io.File;                                                                                     
 117 import java.io.FileDescriptor;                                                                           
 118 import java.io.FileNotFoundException;                                                                    
 119 import java.io.FileOutputStream;                                                                         
 120 import java.io.IOException;                                                                              
 121 import java.io.PrintWriter;                                                                              
 122 import java.lang.reflect.InvocationTargetException;                                                      
 123 import java.lang.reflect.Method;                                                                         
 124 import java.text.DateFormat;                                                                             
 125 import java.util.ArrayList;                                                                              
 126 import java.util.Collection;                                                                             
 127 import java.util.Date;                                                                                   
 128 import java.util.HashMap;                                                                                
 129 import java.util.HashSet;                                                                                
 130 import java.util.List;                                                                                   
 131 import java.util.concurrent.atomic.AtomicInteger;                                                        
 132                                                                                                          
 133 /**                                                                                                      
 134  * Default launcher application.                                                                         
 135  */                                                                                                      
 136 public class Launcher extends Activity                                                                   
 137         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 138                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 139                    LauncherStateTransitionAnimation.Callbacks {                                          
 140     static final String TAG = "Launcher";                                                                
 141     static final boolean LOGD = false;                                                                   
 142                                                                                                          
 143     // Temporary flag                                                                                    
 144     static final boolean DISABLE_ALL_APPS_SEARCH_INTEGRATION = true;                                     
 145                                                                                                          
 146     static final boolean PROFILE_STARTUP = false;                                                        
 147     static final boolean DEBUG_WIDGETS = true;                                                           
 148     static final boolean DEBUG_STRICT_MODE = false;                                                      
 149     static final boolean DEBUG_RESUME_TIME = false;                                                      
 150     static final boolean DEBUG_DUMP_LOG = false;                                                         
 151                                                                                                          
 152     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 153                                                                                                          
 154     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 155     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 156     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 157     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 158                                                                                                          
 159     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 160     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 161                                                                                                          
 162     private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;                                          
 163     private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;                                       
 164     private static final int WORKSPACE_BACKGROUND_BLACK = 2;                                             
 165                                                                                                          
 166     /**                                                                                                  
 167      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 168      * request codes used internally.                                                                    
 169      */                                                                                                  
 170     protected static final int REQUEST_LAST = 100;                                                       
 171                                                                                                          
 172     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 173                                                                                                          
 174     static final int SCREEN_COUNT = 5;                                                                   
 175                                                                                                          
 176     // To turn on these properties, type                                                                 
 177     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 178     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 179                                                                                                          
 180     // The Intent extra that defines whether to ignore the launch animation                              
 181     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 182             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 183                                                                                                          
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE = "launcher.state";                                        
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 192     // Type: int                                                                                         
 193     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 194     // Type: int                                                                                         
 195     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 196     // Type: int                                                                                         
 197     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 198     // Type: int                                                                                         
 199     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 200     // Type: parcelable                                                                                  
 201     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 202     // Type: parcelable                                                                                  
 203     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 204     // Type: int[]                                                                                       
 205     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 206                                                                                                          
 207     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 208     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 209                                                                                                          
 210     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 211     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 212             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 213                                                                                                          
 214     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 215     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 216                                                                                                          
 217     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 218     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 219                                                                                                          
 220     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 221                                                                                                          
 222     /** The different states that Launcher can be in. */                                                 
 223     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };            
 224     @Thunk State mState = State.WORKSPACE;                                                               
 225     @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                   
 226                                                                                                          
 227     private boolean mIsSafeModeEnabled;                                                                  
 228                                                                                                          
 229     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 230     LauncherOverlay mLauncherOverlay;                                                                    
 231     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 232                                                                                                          
 233     static final int APPWIDGET_HOST_ID = 1024;                                                           
 234     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 235     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 236     private static final int ACTIVITY_START_DELAY = 1000;                                                
 237                                                                                                          
 238     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 239     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 240                                                                                                          
 241     // How long to wait before the new-shortcut animation automatically pans the workspace               
 242     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 243     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 244     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                    
 245                                                                                                          
 246     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 247             = new CloseSystemDialogsIntentReceiver();                                                    
 248     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 249                                                                                                          
 250     private LayoutInflater mInflater;                                                                    
 251                                                                                                          
 252     @Thunk Workspace mWorkspace;                                                                         
 253     private View mLauncherView;                                                                          
 254     private View mPageIndicators;                                                                        
 255     @Thunk DragLayer mDragLayer;                                                                         
 256     private DragController mDragController;                                                              
 257     private View mWeightWatcher;                                                                         
 258                                                                                                          
 259     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 260     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 261                                                                                                          
 262     @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                    
 263     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 264     private int mPendingAddWidgetId = -1;                                                                
 265                                                                                                          
 266     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 267                                                                                                          
 268     private Hotseat mHotseat;                                                                            
 269     private ViewGroup mOverviewPanel;                                                                    
 270                                                                                                          
 271     private View mAllAppsButton;                                                                         
 272                                                                                                          
 273     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 274                                                                                                          
 275     // Main container view for the all apps screen.                                                      
 276     @Thunk AllAppsContainerView mAppsView;                                                               
 277                                                                                                          
 278     // Main container view and the model for the widget tray screen.                                     
 279     @Thunk WidgetsContainerView mWidgetsView;                                                            
 280     @Thunk WidgetsModel mWidgetsModel;                                                                   
 281                                                                                                          
 282     private boolean mAutoAdvanceRunning = false;                                                         
 283     private AppWidgetHostView mQsb;                                                                      
 284                                                                                                          
 285     private Bundle mSavedState;                                                                          
 286     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 287     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 288     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 289     private State mOnResumeState = State.NONE;                                                           
 290                                                                                                          
 291     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 292                                                                                                          
 293     @Thunk boolean mWorkspaceLoading = true;                                                             
 294                                                                                                          
 295     private boolean mPaused = true;                                                                      
 296     private boolean mRestoring;                                                                          
 297     private boolean mWaitingForResult;                                                                   
 298     private boolean mOnResumeNeedsLoad;                                                                  
 299                                                                                                          
 300     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 301     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 302                                                                                                          
 303     private Bundle mSavedInstanceState;                                                                  
 304                                                                                                          
 305     private LauncherModel mModel;                                                                        
 306     private IconCache mIconCache;                                                                        
 307     @Thunk boolean mUserPresent = true;                                                                  
 308     private boolean mVisible = false;                                                                    
 309     private boolean mHasFocus = false;                                                                   
 310     private boolean mAttached = false;                                                                   
 311                                                                                                          
 312     @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                       
 313                                                                                                          
 314     private static LongArrayMap<FolderInfo> sFolders = new LongArrayMap<>();                             
 315                                                                                                          
 316     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 317                                                                                                          
 318     // Related to the auto-advancing of widgets                                                          
 319     private final int ADVANCE_MSG = 1;                                                                   
 320     private final int mAdvanceInterval = 20000;                                                          
 321     private final int mAdvanceStagger = 250;                                                             
 322     private long mAutoAdvanceSentTime;                                                                   
 323     private long mAutoAdvanceTimeLeft = -1;                                                              
 324     @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                      
 325         new HashMap<View, AppWidgetProviderInfo>();                                                      
 326                                                                                                          
 327     // Determines how long to wait after a rotation before restoring the screen orientation to           
 328     // match the sensor state.                                                                           
 329     private final int mRestoreScreenOrientationDelay = 500;                                              
 330                                                                                                          
 331     @Thunk Drawable mWorkspaceBackgroundDrawable;                                                        
 332                                                                                                          
 333     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 334     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 335                                                                                                          
 336     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 337     static Date sDateStamp = new Date();                                                                 
 338     static DateFormat sDateFormat =                                                                      
 339             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 340     static long sRunStart = System.currentTimeMillis();                                                  
 341     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 342                                                                                                          
 343     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 344     // it from the context.                                                                              
 345     private SharedPreferences mSharedPrefs;                                                              
 346                                                                                                          
 347     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 348     // when we scroll to that page on resume.                                                            
 349     @Thunk ImageView mFolderIconImageView;                                                               
 350     private Bitmap mFolderIconBitmap;                                                                    
 351     private Canvas mFolderIconCanvas;                                                                    
 352     private Rect mRectForFolderAnimation = new Rect();                                                   
 353                                                                                                          
 354     private DeviceProfile mDeviceProfile;                                                                
 355                                                                                                          
 356     // This is set to the view that launched the activity that navigated the user away from              
 357     // launcher. Since there is no callback for when the activity has finished launching, enable         
 358     // the press state and keep this reference to reset the press state when we return to launcher.      
 359     private BubbleTextView mWaitingForResume;                                                            
 360                                                                                                          
 361     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 362             new HashMap<String, CustomAppWidget>();                                                      
 363                                                                                                          
 364     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 365     static {                                                                                             
 366         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 367             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 368         }                                                                                                
 369     }                                                                                                    
 370                                                                                                          
 371     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 372     private static Method sClipRevealMethod = null;                                                      
 373     static {                                                                                             
 374         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 375         try {                                                                                            
 376             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 377                     View.class, int.class, int.class, int.class, int.class);                             
 378         } catch (Exception e) {                                                                          
 379             // Earlier version                                                                           
 380         }                                                                                                
 381     }                                                                                                    
 382                                                                                                          
 383     @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                              
 384         public void run() {                                                                              
 385             if (mWorkspace != null) {                                                                    
 386                 mWorkspace.buildPageHardwareLayers();                                                    
 387             }                                                                                            
 388         }                                                                                                
 389     };                                                                                                   
 390                                                                                                          
 391     private static PendingAddArguments sPendingAddItem;                                                  
 392                                                                                                          
 393     @Thunk static class PendingAddArguments {                                                            
 394         int requestCode;                                                                                 
 395         Intent intent;                                                                                   
 396         long container;                                                                                  
 397         long screenId;                                                                                   
 398         int cellX;                                                                                       
 399         int cellY;                                                                                       
 400         int appWidgetId;                                                                                 
 401     }                                                                                                    
 402                                                                                                          
 403     private Stats mStats;                                                                                
 404                                                                                                          
 405     FocusIndicatorView mFocusHandler;                                                                    
 406                                                                                                          
 407     @Override                                                                                            
 408     protected void onCreate(Bundle savedInstanceState) {                                                 
 409         if (DEBUG_STRICT_MODE) {                                                                         
 410             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 411                     .detectDiskReads()                                                                   
 412                     .detectDiskWrites()                                                                  
 413                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 414                     .penaltyLog()                                                                        
 415                     .build());                                                                           
 416             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 417                     .detectLeakedSqlLiteObjects()                                                        
 418                     .detectLeakedClosableObjects()                                                       
 419                     .penaltyLog()                                                                        
 420                     .penaltyDeath()                                                                      
 421                     .build());                                                                           
 422         }                                                                                                
 423                                                                                                          
 424         if (mLauncherCallbacks != null) {                                                                
 425             mLauncherCallbacks.preOnCreate();                                                            
 426         }                                                                                                
 427                                                                                                          
 428         super.onCreate(savedInstanceState);                                                              
 429                                                                                                          
 430         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 431         LauncherAppState app = LauncherAppState.getInstance();                                           
 432         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 433                                                                                                          
 434         // Load configuration-specific DeviceProfile                                                     
 435         mDeviceProfile = getResources().getConfiguration().orientation                                   
 436                 == Configuration.ORIENTATION_LANDSCAPE ?                                                 
 437                         app.getInvariantDeviceProfile().landscapeProfile                                 
 438                             : app.getInvariantDeviceProfile().portraitProfile;                           
 439                                                                                                          
 440         // TODO: Move this to icon cache.                                                                
 441         Utilities.setIconSize(mDeviceProfile.iconSizePx);                                                
 442                                                                                                          
 443         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 444         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 445                 Context.MODE_PRIVATE);                                                                   
 446         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 447         mModel = app.setLauncher(this);                                                                  
 448         mIconCache = app.getIconCache();                                                                 
 449                                                                                                          
 450         mDragController = new DragController(this);                                                      
 451         mInflater = getLayoutInflater();                                                                 
 452         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 453                                                                                                          
 454         mStats = new Stats(this);                                                                        
 455                                                                                                          
 456         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 457                                                                                                          
 458         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 459         mAppWidgetHost.startListening();                                                                 
 460                                                                                                          
 461         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 462         // this also ensures that any synchronous binding below doesn't re-trigger another               
 463         // LauncherModel load.                                                                           
 464         mPaused = false;                                                                                 
 465                                                                                                          
 466         if (PROFILE_STARTUP) {                                                                           
 467             android.os.Debug.startMethodTracing(                                                         
 468                     Environment.getExternalStorageDirectory() + "/launcher");                            
 469         }                                                                                                
 470                                                                                                          
 471         checkForLocaleChange();                                                                          
 472         setContentView(R.layout.launcher);                                                               
 473                                                                                                          
 474         setupViews();                                                                                    
 475         mDeviceProfile.layout(this);                                                                     
 476                                                                                                          
 477         registerContentObservers();                                                                      
 478                                                                                                          
 479         lockAllApps();                                                                                   
 480                                                                                                          
 481         mSavedState = savedInstanceState;                                                                
 482         restoreState(mSavedState);                                                                       
 483                                                                                                          
 484         if (PROFILE_STARTUP) {                                                                           
 485             android.os.Debug.stopMethodTracing();                                                        
 486         }                                                                                                
 487                                                                                                          
 488         if (!mRestoring) {                                                                               
 489             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 490                 // If the user leaves launcher, then we should just load items asynchronously when       
 491                 // they return.                                                                          
 492                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                      
 493             } else {                                                                                     
 494                 // We only load the page synchronously if the user rotates (or triggers a                
 495                 // configuration change) while launcher is in the foreground                             
 496                 mModel.startLoader(mWorkspace.getRestorePage());                                         
 497             }                                                                                            
 498         }                                                                                                
 499                                                                                                          
 500         // For handling default keys                                                                     
 501         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 502         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 503                                                                                                          
 504         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 505         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 506                                                                                                          
 507         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 508         unlockScreenOrientation(true);                                                                   
 509                                                                                                          
 510         if (mLauncherCallbacks != null) {                                                                
 511             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 512             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 513                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 514                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 515                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 516                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 517                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 518             }                                                                                            
 519         }                                                                                                
 520                                                                                                          
 521         if (shouldShowIntroScreen()) {                                                                   
 522             showIntroScreen();                                                                           
 523         } else {                                                                                         
 524             showFirstRunActivity();                                                                      
 525             showFirstRunClings();                                                                        
 526         }                                                                                                
 527     }                                                                                                    
 528                                                                                                          
 529     private LauncherCallbacks mLauncherCallbacks;                                                        
 530                                                                                                          
 531     public void onPostCreate(Bundle savedInstanceState) {                                                
 532         super.onPostCreate(savedInstanceState);                                                          
 533         if (mLauncherCallbacks != null) {                                                                
 534             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 535         }                                                                                                
 536     }                                                                                                    
 537                                                                                                          
 538     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 539         mLauncherCallbacks = callbacks;                                                                  
 540         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 541             @Override                                                                                    
 542             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 543                 if (LOGD) {                                                                              
 544                     Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);                               
 545                 }                                                                                        
 546                 mAppsView.setFixedBounds(bounds);                                                        
 547                 mWidgetsView.setFixedBounds(bounds);                                                     
 548             }                                                                                            
 549                                                                                                          
 550             @Override                                                                                    
 551             public void dismissAllApps() {                                                               
 552                 if (!DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
 553                     // Dismiss All Apps if we aren't already paused/invisible                            
 554                     if (!mPaused) {                                                                      
 555                         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true,    
 556                                 null /* onCompleteRunnable */, false /* notifyLauncherCallbacks */);     
 557                     }                                                                                    
 558                 }                                                                                        
 559             }                                                                                            
 560         });                                                                                              
 561         return true;                                                                                     
 562     }                                                                                                    
 563                                                                                                          
 564     @Override                                                                                            
 565     public void onLauncherProviderChange() {                                                             
 566         if (mLauncherCallbacks != null) {                                                                
 567             mLauncherCallbacks.onLauncherProviderChange();                                               
 568         }                                                                                                
 569     }                                                                                                    
 570                                                                                                          
 571     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 572     protected boolean hasCustomContentToLeft() {                                                         
 573         if (mLauncherCallbacks != null) {                                                                
 574             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 575         }                                                                                                
 576         return false;                                                                                    
 577     }                                                                                                    
 578                                                                                                          
 579     /**                                                                                                  
 580      * To be overridden by subclasses to populate the custom content container and call                  
 581      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 582      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 583      */                                                                                                  
 584     protected void populateCustomContentContainer() {                                                    
 585         if (mLauncherCallbacks != null) {                                                                
 586             mLauncherCallbacks.populateCustomContentContainer();                                         
 587         }                                                                                                
 588     }                                                                                                    
 589                                                                                                          
 590     /**                                                                                                  
 591      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 592      * ensure the custom content page is added or removed if necessary.                                  
 593      */                                                                                                  
 594     protected void invalidateHasCustomContentToLeft() {                                                  
 595         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 596             // Not bound yet, wait for bindScreens to be called.                                         
 597             return;                                                                                      
 598         }                                                                                                
 599                                                                                                          
 600         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 601             // Create the custom content page and call the subclass to populate it.                      
 602             mWorkspace.createCustomContentContainer();                                                   
 603             populateCustomContentContainer();                                                            
 604         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 605             mWorkspace.removeCustomContentPage();                                                        
 606         }                                                                                                
 607     }                                                                                                    
 608                                                                                                          
 609     @Thunk void checkForLocaleChange() {                                                                 
 610         if (sLocaleConfiguration == null) {                                                              
 611             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 612                 @Override                                                                                
 613                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 614                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 615                     readConfiguration(Launcher.this, localeConfiguration);                               
 616                     return localeConfiguration;                                                          
 617                 }                                                                                        
 618                                                                                                          
 619                 @Override                                                                                
 620                 protected void onPostExecute(LocaleConfiguration result) {                               
 621                     sLocaleConfiguration = result;                                                       
 622                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 623                 }                                                                                        
 624             }.execute();                                                                                 
 625             return;                                                                                      
 626         }                                                                                                
 627                                                                                                          
 628         final Configuration configuration = getResources().getConfiguration();                           
 629                                                                                                          
 630         final String previousLocale = sLocaleConfiguration.locale;                                       
 631         final String locale = configuration.locale.toString();                                           
 632                                                                                                          
 633         final int previousMcc = sLocaleConfiguration.mcc;                                                
 634         final int mcc = configuration.mcc;                                                               
 635                                                                                                          
 636         final int previousMnc = sLocaleConfiguration.mnc;                                                
 637         final int mnc = configuration.mnc;                                                               
 638                                                                                                          
 639         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 640                                                                                                          
 641         if (localeChanged) {                                                                             
 642             sLocaleConfiguration.locale = locale;                                                        
 643             sLocaleConfiguration.mcc = mcc;                                                              
 644             sLocaleConfiguration.mnc = mnc;                                                              
 645                                                                                                          
 646             mIconCache.flush();                                                                          
 647                                                                                                          
 648             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 649             new AsyncTask<Void, Void, Void>() {                                                          
 650                 public Void doInBackground(Void ... args) {                                              
 651                     writeConfiguration(Launcher.this, localeConfiguration);                              
 652                     return null;                                                                         
 653                 }                                                                                        
 654             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 655         }                                                                                                
 656     }                                                                                                    
 657                                                                                                          
 658     @Thunk static class LocaleConfiguration {                                                            
 659         public String locale;                                                                            
 660         public int mcc = -1;                                                                             
 661         public int mnc = -1;                                                                             
 662     }                                                                                                    
 663                                                                                                          
 664     @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {           
 665         DataInputStream in = null;                                                                       
 666         try {                                                                                            
 667             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 668             configuration.locale = in.readUTF();                                                         
 669             configuration.mcc = in.readInt();                                                            
 670             configuration.mnc = in.readInt();                                                            
 671         } catch (FileNotFoundException e) {                                                              
 672             // Ignore                                                                                    
 673         } catch (IOException e) {                                                                        
 674             // Ignore                                                                                    
 675         } finally {                                                                                      
 676             if (in != null) {                                                                            
 677                 try {                                                                                    
 678                     in.close();                                                                          
 679                 } catch (IOException e) {                                                                
 680                     // Ignore                                                                            
 681                 }                                                                                        
 682             }                                                                                            
 683         }                                                                                                
 684     }                                                                                                    
 685                                                                                                          
 686     @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {          
 687         DataOutputStream out = null;                                                                     
 688         try {                                                                                            
 689             out = new DataOutputStream(context.openFileOutput(                                           
 690                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 691             out.writeUTF(configuration.locale);                                                          
 692             out.writeInt(configuration.mcc);                                                             
 693             out.writeInt(configuration.mnc);                                                             
 694             out.flush();                                                                                 
 695         } catch (FileNotFoundException e) {                                                              
 696             // Ignore                                                                                    
 697         } catch (IOException e) {                                                                        
 698             //noinspection ResultOfMethodCallIgnored                                                     
 699             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 700         } finally {                                                                                      
 701             if (out != null) {                                                                           
 702                 try {                                                                                    
 703                     out.close();                                                                         
 704                 } catch (IOException e) {                                                                
 705                     // Ignore                                                                            
 706                 }                                                                                        
 707             }                                                                                            
 708         }                                                                                                
 709     }                                                                                                    
 710                                                                                                          
 711     public Stats getStats() {                                                                            
 712         return mStats;                                                                                   
 713     }                                                                                                    
 714                                                                                                          
 715     public LayoutInflater getInflater() {                                                                
 716         return mInflater;                                                                                
 717     }                                                                                                    
 718                                                                                                          
 719     public boolean isDraggingEnabled() {                                                                 
 720         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 721         // that is subsequently removed from the workspace in startBinding().                            
 722         return !mModel.isLoadingWorkspace();                                                             
 723     }                                                                                                    
 724                                                                                                          
 725     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 726     public static int generateViewId() {                                                                 
 727         if (Build.VERSION.SDK_INT >= 17) {                                                               
 728             return View.generateViewId();                                                                
 729         } else {                                                                                         
 730             // View.generateViewId() is not available. The following fallback logic is a copy            
 731             // of its implementation.                                                                    
 732             for (;;) {                                                                                   
 733                 final int result = sNextGeneratedId.get();                                               
 734                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 735                 int newValue = result + 1;                                                               
 736                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 737                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 738                     return result;                                                                       
 739                 }                                                                                        
 740             }                                                                                            
 741         }                                                                                                
 742     }                                                                                                    
 743                                                                                                          
 744     public int getViewIdForItem(ItemInfo info) {                                                         
 745         // This cast is safe given the > 2B range for int.                                               
 746         int itemId = (int) info.id;                                                                      
 747         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 748             return mItemIdToViewId.get(itemId);                                                          
 749         }                                                                                                
 750         int viewId = generateViewId();                                                                   
 751         mItemIdToViewId.put(itemId, viewId);                                                             
 752         return viewId;                                                                                   
 753     }                                                                                                    
 754                                                                                                          
 755     /**                                                                                                  
 756      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 757      * a configuration step, this allows the proper animations to run after other transitions.           
 758      */                                                                                                  
 759     private long completeAdd(PendingAddArguments args) {                                                 
 760         long screenId = args.screenId;                                                                   
 761         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 762             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 763             // that the drop page actually exists.                                                       
 764             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 765         }                                                                                                
 766                                                                                                          
 767         switch (args.requestCode) {                                                                      
 768             case REQUEST_CREATE_SHORTCUT:                                                                
 769                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 770                         args.cellY);                                                                     
 771                 break;                                                                                   
 772             case REQUEST_CREATE_APPWIDGET:                                                               
 773                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 774                 break;                                                                                   
 775             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 776                 completeRestoreAppWidget(args.appWidgetId);                                              
 777                 break;                                                                                   
 778         }                                                                                                
 779         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 780         // if you turned the screen off and then back while in All Apps, Launcher would not              
 781         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 782         resetAddInfo();                                                                                  
 783         return screenId;                                                                                 
 784     }                                                                                                    
 785                                                                                                          
 786     private void handleActivityResult(                                                                   
 787             final int requestCode, final int resultCode, final Intent data) {                            
 788         // Reset the startActivity waiting flag                                                          
 789         setWaitingForResult(false);                                                                      
 790         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 791         mPendingAddWidgetId = -1;                                                                        
 792                                                                                                          
 793         Runnable exitSpringLoaded = new Runnable() {                                                     
 794             @Override                                                                                    
 795             public void run() {                                                                          
 796                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 797                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 798             }                                                                                            
 799         };                                                                                               
 800                                                                                                          
 801         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 802             final int appWidgetId = data != null ?                                                       
 803                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 804             if (resultCode == RESULT_CANCELED) {                                                         
 805                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 806                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 807                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 808             } else if (resultCode == RESULT_OK) {                                                        
 809                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 810                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 811             }                                                                                            
 812             return;                                                                                      
 813         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 814             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 815                 showWorkspace(false);                                                                    
 816             }                                                                                            
 817             return;                                                                                      
 818         }                                                                                                
 819                                                                                                          
 820         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 821                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 822                                                                                                          
 823         final boolean workspaceLocked = isWorkspaceLocked();                                             
 824         // We have special handling for widgets                                                          
 825         if (isWidgetDrop) {                                                                              
 826             final int appWidgetId;                                                                       
 827             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 828                     : -1;                                                                                
 829             if (widgetId < 0) {                                                                          
 830                 appWidgetId = pendingAddWidgetId;                                                        
 831             } else {                                                                                     
 832                 appWidgetId = widgetId;                                                                  
 833             }                                                                                            
 834                                                                                                          
 835             final int result;                                                                            
 836             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 837                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 838                         "returned from the widget configuration activity.");                             
 839                 result = RESULT_CANCELED;                                                                
 840                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 841                 final Runnable onComplete = new Runnable() {                                             
 842                     @Override                                                                            
 843                     public void run() {                                                                  
 844                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 845                     }                                                                                    
 846                 };                                                                                       
 847                 if (workspaceLocked) {                                                                   
 848                     // No need to remove the empty screen if we're mid-binding, as the                   
 849                     // the bind will not add the empty screen.                                           
 850                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 851                 } else {                                                                                 
 852                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 853                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 854                 }                                                                                        
 855             } else {                                                                                     
 856                 if (!workspaceLocked) {                                                                  
 857                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 858                         // When the screen id represents an actual screen (as opposed to a rank)         
 859                         // we make sure that the drop page actually exists.                              
 860                         mPendingAddInfo.screenId =                                                       
 861                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 862                     }                                                                                    
 863                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 864                                                                                                          
 865                     dropLayout.setDropPending(true);                                                     
 866                     final Runnable onComplete = new Runnable() {                                         
 867                         @Override                                                                        
 868                         public void run() {                                                              
 869                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 870                             dropLayout.setDropPending(false);                                            
 871                         }                                                                                
 872                     };                                                                                   
 873                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 874                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 875                 } else {                                                                                 
 876                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 877                             mPendingAddInfo);                                                            
 878                     sPendingAddItem = args;                                                              
 879                 }                                                                                        
 880             }                                                                                            
 881             return;                                                                                      
 882         }                                                                                                
 883                                                                                                          
 884         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 885             if (resultCode == RESULT_OK) {                                                               
 886                 // Update the widget view.                                                               
 887                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 888                         pendingAddWidgetId, mPendingAddInfo);                                            
 889                 if (workspaceLocked) {                                                                   
 890                     sPendingAddItem = args;                                                              
 891                 } else {                                                                                 
 892                     completeAdd(args);                                                                   
 893                 }                                                                                        
 894             }                                                                                            
 895             // Leave the widget in the pending state if the user canceled the configure.                 
 896             return;                                                                                      
 897         }                                                                                                
 898                                                                                                          
 899         // The pattern used here is that a user PICKs a specific application,                            
 900         // which, depending on the target, might need to CREATE the actual target.                       
 901                                                                                                          
 902         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 903         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 904         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 905             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 906                     mPendingAddInfo);                                                                    
 907             if (isWorkspaceLocked()) {                                                                   
 908                 sPendingAddItem = args;                                                                  
 909             } else {                                                                                     
 910                 completeAdd(args);                                                                       
 911                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 912                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 913             }                                                                                            
 914         } else if (resultCode == RESULT_CANCELED) {                                                      
 915             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 916                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 917         }                                                                                                
 918         mDragLayer.clearAnimatedView();                                                                  
 919                                                                                                          
 920     }                                                                                                    
 921                                                                                                          
 922     @Override                                                                                            
 923     protected void onActivityResult(                                                                     
 924             final int requestCode, final int resultCode, final Intent data) {                            
 925         handleActivityResult(requestCode, resultCode, data);                                             
 926         if (mLauncherCallbacks != null) {                                                                
 927             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 928         }                                                                                                
 929     }                                                                                                    
 930                                                                                                          
 931     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 932             appWidgetId, ItemInfo info) {                                                                
 933         PendingAddArguments args = new PendingAddArguments();                                            
 934         args.requestCode = requestCode;                                                                  
 935         args.intent = data;                                                                              
 936         args.container = info.container;                                                                 
 937         args.screenId = info.screenId;                                                                   
 938         args.cellX = info.cellX;                                                                         
 939         args.cellY = info.cellY;                                                                         
 940         args.appWidgetId = appWidgetId;                                                                  
 941         return args;                                                                                     
 942     }                                                                                                    
 943                                                                                                          
 944     /**                                                                                                  
 945      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 946      *                                                                                                   
 947      * @param screenId the screen id to check                                                            
 948      * @return the new screen, or screenId if it exists                                                  
 949      */                                                                                                  
 950     private long ensurePendingDropLayoutExists(long screenId) {                                          
 951         CellLayout dropLayout =                                                                          
 952                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 953         if (dropLayout == null) {                                                                        
 954             // it's possible that the add screen was removed because it was                              
 955             // empty and a re-bind occurred                                                              
 956             mWorkspace.addExtraEmptyScreen();                                                            
 957             return mWorkspace.commitExtraEmptyScreen();                                                  
 958         } else {                                                                                         
 959             return screenId;                                                                             
 960         }                                                                                                
 961     }                                                                                                    
 962                                                                                                          
 963     @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                
 964         CellLayout cellLayout =                                                                          
 965                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 966         Runnable onCompleteRunnable = null;                                                              
 967         int animationType = 0;                                                                           
 968                                                                                                          
 969         AppWidgetHostView boundWidget = null;                                                            
 970         if (resultCode == RESULT_OK) {                                                                   
 971             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 972             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 973                     mPendingAddWidgetInfo);                                                              
 974             boundWidget = layout;                                                                        
 975             onCompleteRunnable = new Runnable() {                                                        
 976                 @Override                                                                                
 977                 public void run() {                                                                      
 978                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 979                             mPendingAddInfo.screenId, layout, null);                                     
 980                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 981                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 982                 }                                                                                        
 983             };                                                                                           
 984         } else if (resultCode == RESULT_CANCELED) {                                                      
 985             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 986             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 987         }                                                                                                
 988         if (mDragLayer.getAnimatedView() != null) {                                                      
 989             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 990                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 991                     animationType, boundWidget, true);                                                   
 992         } else if (onCompleteRunnable != null) {                                                         
 993             // The animated view may be null in the case of a rotation during widget configuration       
 994             onCompleteRunnable.run();                                                                    
 995         }                                                                                                
 996     }                                                                                                    
 997                                                                                                          
 998     @Override                                                                                            
 999     protected void onStop() {                                                                            
1000         super.onStop();                                                                                  
1001         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1002                                                                                                          
1003         if (mLauncherCallbacks != null) {                                                                
1004             mLauncherCallbacks.onStop();                                                                 
1005         }                                                                                                
1006     }                                                                                                    
1007                                                                                                          
1008     @Override                                                                                            
1009     protected void onStart() {                                                                           
1010         super.onStart();                                                                                 
1011         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1012                                                                                                          
1013         if (mLauncherCallbacks != null) {                                                                
1014             mLauncherCallbacks.onStart();                                                                
1015         }                                                                                                
1016     }                                                                                                    
1017                                                                                                          
1018     @Override                                                                                            
1019     protected void onResume() {                                                                          
1020         long startTime = 0;                                                                              
1021         if (DEBUG_RESUME_TIME) {                                                                         
1022             startTime = System.currentTimeMillis();                                                      
1023             Log.v(TAG, "Launcher.onResume()");                                                           
1024         }                                                                                                
1025                                                                                                          
1026         if (mLauncherCallbacks != null) {                                                                
1027             mLauncherCallbacks.preOnResume();                                                            
1028         }                                                                                                
1029                                                                                                          
1030         super.onResume();                                                                                
1031                                                                                                          
1032         // Restore the previous launcher state                                                           
1033         if (mOnResumeState == State.WORKSPACE) {                                                         
1034             showWorkspace(false);                                                                        
1035         } else if (mOnResumeState == State.APPS) {                                                       
1036             boolean launchedFromApp = (mWaitingForResume != null);                                       
1037             // Don't update the predicted apps if the user is returning to launcher in the apps          
1038             // view after launching an app, as they may be depending on the UI to be static to           
1039             // switch to another app, otherwise, if it was                                               
1040             showAppsView(false /* animated */, false /* resetListToTop */,                               
1041                     !launchedFromApp /* updatePredictedApps */);                                         
1042         } else if (mOnResumeState == State.WIDGETS) {                                                    
1043             showWidgetsView(false, false);                                                               
1044         }                                                                                                
1045         mOnResumeState = State.NONE;                                                                     
1046                                                                                                          
1047         // Restore the apps state if we are in all apps                                                  
1048         if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                             
1049             // Otherwise, notify the callbacks if we are in all apps mode                                
1050             if (mState == State.APPS) {                                                                  
1051                 if (mLauncherCallbacks != null) {                                                        
1052                     mLauncherCallbacks.onAllAppsShown();                                                 
1053                 }                                                                                        
1054             }                                                                                            
1055         }                                                                                                
1056                                                                                                          
1057         // Background was set to gradient in onPause(), restore to transparent if in all apps.           
1058         setWorkspaceBackground(mState == State.WORKSPACE ? WORKSPACE_BACKGROUND_TRANSPARENT              
1059                 : WORKSPACE_BACKGROUND_GRADIENT);                                                        
1060                                                                                                          
1061         mPaused = false;                                                                                 
1062         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1063             setWorkspaceLoading(true);                                                                   
1064             mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                          
1065             mRestoring = false;                                                                          
1066             mOnResumeNeedsLoad = false;                                                                  
1067         }                                                                                                
1068         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1069             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1070             // execute them here                                                                         
1071             long startTimeCallbacks = 0;                                                                 
1072             if (DEBUG_RESUME_TIME) {                                                                     
1073                 startTimeCallbacks = System.currentTimeMillis();                                         
1074             }                                                                                            
1075                                                                                                          
1076             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1077                 mBindOnResumeCallbacks.get(i).run();                                                     
1078             }                                                                                            
1079             mBindOnResumeCallbacks.clear();                                                              
1080             if (DEBUG_RESUME_TIME) {                                                                     
1081                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1082                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1083             }                                                                                            
1084         }                                                                                                
1085         if (mOnResumeCallbacks.size() > 0) {                                                             
1086             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1087                 mOnResumeCallbacks.get(i).run();                                                         
1088             }                                                                                            
1089             mOnResumeCallbacks.clear();                                                                  
1090         }                                                                                                
1091                                                                                                          
1092         // Reset the pressed state of icons that were locked in the press state while activities         
1093         // were launching                                                                                
1094         if (mWaitingForResume != null) {                                                                 
1095             // Resets the previous workspace icon press state                                            
1096             mWaitingForResume.setStayPressed(false);                                                     
1097         }                                                                                                
1098                                                                                                          
1099         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1100         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1101         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1102         // orientation.                                                                                  
1103         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1104         reinflateQSBIfNecessary();                                                                       
1105                                                                                                          
1106         if (DEBUG_RESUME_TIME) {                                                                         
1107             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1108         }                                                                                                
1109                                                                                                          
1110         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1111             // If we are resuming and the custom content is the current page, we call onShow().          
1112             // It is also poassible that onShow will instead be called slightly after first layout       
1113             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1114             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1115                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1116             }                                                                                            
1117         }                                                                                                
1118         updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());                                
1119         mWorkspace.onResume();                                                                           
1120                                                                                                          
1121         if (!isWorkspaceLoading()) {                                                                     
1122             // Process any items that were added while Launcher was away.                                
1123             InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                   
1124         }                                                                                                
1125                                                                                                          
1126         if (mLauncherCallbacks != null) {                                                                
1127             mLauncherCallbacks.onResume();                                                               
1128         }                                                                                                
1129     }                                                                                                    
1130                                                                                                          
1131     @Override                                                                                            
1132     protected void onPause() {                                                                           
1133         // Ensure that items added to Launcher are queued until Launcher returns                         
1134         InstallShortcutReceiver.enableInstallQueue();                                                    
1135                                                                                                          
1136         super.onPause();                                                                                 
1137         mPaused = true;                                                                                  
1138         mDragController.cancelDrag();                                                                    
1139         mDragController.resetLastGestureUpTime();                                                        
1140                                                                                                          
1141         // We call onHide() aggressively. The custom content callbacks should be able to                 
1142         // debounce excess onHide calls.                                                                 
1143         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1144             mWorkspace.getCustomContentCallbacks().onHide();                                             
1145         }                                                                                                
1146                                                                                                          
1147         if (mLauncherCallbacks != null) {                                                                
1148             mLauncherCallbacks.onPause();                                                                
1149         }                                                                                                
1150     }                                                                                                    
1151                                                                                                          
1152     public interface CustomContentCallbacks {                                                            
1153         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1154         // by a onResume or by scrolling otherwise.                                                      
1155         public void onShow(boolean fromResume);                                                          
1156                                                                                                          
1157         // Custom content is completely hidden                                                           
1158         public void onHide();                                                                            
1159                                                                                                          
1160         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1161         public void onScrollProgressChanged(float progress);                                             
1162                                                                                                          
1163         // Indicates whether the user is allowed to scroll away from the custom content.                 
1164         boolean isScrollingAllowed();                                                                    
1165     }                                                                                                    
1166                                                                                                          
1167     public interface LauncherOverlay {                                                                   
1168                                                                                                          
1169         /**                                                                                              
1170          * Touch interaction leading to overscroll has begun                                             
1171          */                                                                                              
1172         public void onScrollInteractionBegin();                                                          
1173                                                                                                          
1174         /**                                                                                              
1175          * Touch interaction related to overscroll has ended                                             
1176          */                                                                                              
1177         public void onScrollInteractionEnd();                                                            
1178                                                                                                          
1179         /**                                                                                              
1180          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1181          * screen (or in the case of RTL, the rightmost screen).                                         
1182          */                                                                                              
1183         public void onScrollChange(int progress, boolean rtl);                                           
1184                                                                                                          
1185         /**                                                                                              
1186          * Screen has stopped scrolling                                                                  
1187          */                                                                                              
1188         public void onScrollSettled();                                                                   
1189                                                                                                          
1190         /**                                                                                              
1191          * This method can be called by the Launcher in order to force the LauncherOverlay               
1192          * to exit fully immersive mode.                                                                 
1193          */                                                                                              
1194         public void forceExitFullImmersion();                                                            
1195     }                                                                                                    
1196                                                                                                          
1197     public interface LauncherAppsCallbacks {                                                             
1198         /**                                                                                              
1199          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1200          * any other views.                                                                              
1201          */                                                                                              
1202         public void onAllAppsBoundsChanged(Rect bounds);                                                 
1203                                                                                                          
1204         /**                                                                                              
1205          * Called to dismiss all apps if it is showing.                                                  
1206          */                                                                                              
1207         public void dismissAllApps();                                                                    
1208     }                                                                                                    
1209                                                                                                          
1210     public interface LauncherOverlayCallbacks {                                                          
1211         /**                                                                                              
1212          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1213          * however it doesn't modify any state within the launcher.                                      
1214          */                                                                                              
1215         public boolean canEnterFullImmersion();                                                          
1216                                                                                                          
1217         /**                                                                                              
1218          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1219          * eg. by occupying the full screen and handling all touch events.                               
1220          *                                                                                               
1221          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1222          *          case, Launcher will modify any necessary state and assumes the overlay is            
1223          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1224          *                                                                                               
1225          */                                                                                              
1226         public boolean enterFullImmersion();                                                             
1227                                                                                                          
1228         /**                                                                                              
1229          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1230          * full control over UI and state.                                                               
1231          */                                                                                              
1232         public void exitFullImmersion();                                                                 
1233     }                                                                                                    
1234                                                                                                          
1235     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1236                                                                                                          
1237         @Override                                                                                        
1238         public boolean canEnterFullImmersion() {                                                         
1239             return mState == State.WORKSPACE;                                                            
1240         }                                                                                                
1241                                                                                                          
1242         @Override                                                                                        
1243         public boolean enterFullImmersion() {                                                            
1244             if (mState == State.WORKSPACE) {                                                             
1245                 // When fully immersed, disregard any touches which fall through.                        
1246                 mDragLayer.setBlockTouch(true);                                                          
1247                 return true;                                                                             
1248             }                                                                                            
1249             return false;                                                                                
1250         }                                                                                                
1251                                                                                                          
1252         @Override                                                                                        
1253         public void exitFullImmersion() {                                                                
1254             mDragLayer.setBlockTouch(false);                                                             
1255         }                                                                                                
1256     }                                                                                                    
1257                                                                                                          
1258     protected boolean hasSettings() {                                                                    
1259         if (mLauncherCallbacks != null) {                                                                
1260             return mLauncherCallbacks.hasSettings();                                                     
1261         }                                                                                                
1262         return false;                                                                                    
1263     }                                                                                                    
1264                                                                                                          
1265     public void addToCustomContentPage(View customContent,                                               
1266             CustomContentCallbacks callbacks, String description) {                                      
1267         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1268     }                                                                                                    
1269                                                                                                          
1270     // The custom content needs to offset its content to account for the QSB                             
1271     public int getTopOffsetForCustomContent() {                                                          
1272         return mWorkspace.getPaddingTop();                                                               
1273     }                                                                                                    
1274                                                                                                          
1275     @Override                                                                                            
1276     public Object onRetainNonConfigurationInstance() {                                                   
1277         // Flag the loader to stop early before switching                                                
1278         if (mModel.isCurrentCallbacks(this)) {                                                           
1279             mModel.stopLoader();                                                                         
1280         }                                                                                                
1281         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1282                                                                                                          
1283         return Boolean.TRUE;                                                                             
1284     }                                                                                                    
1285                                                                                                          
1286     // We can't hide the IME if it was forced open.  So don't bother                                     
1287     @Override                                                                                            
1288     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1289         super.onWindowFocusChanged(hasFocus);                                                            
1290         mHasFocus = hasFocus;                                                                            
1291                                                                                                          
1292         if (mLauncherCallbacks != null) {                                                                
1293             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1294         }                                                                                                
1295     }                                                                                                    
1296                                                                                                          
1297     private boolean acceptFilter() {                                                                     
1298         final InputMethodManager inputManager = (InputMethodManager)                                     
1299                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1300         return !inputManager.isFullscreenMode();                                                         
1301     }                                                                                                    
1302                                                                                                          
1303     @Override                                                                                            
1304     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1305         final int uniChar = event.getUnicodeChar();                                                      
1306         final boolean handled = super.onKeyDown(keyCode, event);                                         
1307         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1308         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1309             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1310                     keyCode, event);                                                                     
1311             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1312                 // something usable has been typed - start a search                                      
1313                 // the typed text will be retrieved and cleared by                                       
1314                 // showSearchDialog()                                                                    
1315                 // If there are multiple keystrokes before the search dialog takes focus,                
1316                 // onSearchRequested() will be called for every keystroke,                               
1317                 // but it is idempotent, so it's fine.                                                   
1318                 return onSearchRequested();                                                              
1319             }                                                                                            
1320         }                                                                                                
1321                                                                                                          
1322         // Eat the long press event so the keyboard doesn't come up.                                     
1323         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1324             return true;                                                                                 
1325         }                                                                                                
1326                                                                                                          
1327         return handled;                                                                                  
1328     }                                                                                                    
1329                                                                                                          
1330     private String getTypedText() {                                                                      
1331         return mDefaultKeySsb.toString();                                                                
1332     }                                                                                                    
1333                                                                                                          
1334     private void clearTypedText() {                                                                      
1335         mDefaultKeySsb.clear();                                                                          
1336         mDefaultKeySsb.clearSpans();                                                                     
1337         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1338     }                                                                                                    
1339                                                                                                          
1340     /**                                                                                                  
1341      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1342      * State                                                                                             
1343      */                                                                                                  
1344     private static State intToState(int stateOrdinal) {                                                  
1345         State state = State.WORKSPACE;                                                                   
1346         final State[] stateValues = State.values();                                                      
1347         for (int i = 0; i < stateValues.length; i++) {                                                   
1348             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1349                 state = stateValues[i];                                                                  
1350                 break;                                                                                   
1351             }                                                                                            
1352         }                                                                                                
1353         return state;                                                                                    
1354     }                                                                                                    
1355                                                                                                          
1356     /**                                                                                                  
1357      * Restores the previous state, if it exists.                                                        
1358      *                                                                                                   
1359      * @param savedState The previous state.                                                             
1360      */                                                                                                  
1361     @SuppressWarnings("unchecked")                                                                       
1362     private void restoreState(Bundle savedState) {                                                       
1363         if (savedState == null) {                                                                        
1364             return;                                                                                      
1365         }                                                                                                
1366                                                                                                          
1367         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1368         if (state == State.APPS || state == State.WIDGETS) {                                             
1369             mOnResumeState = state;                                                                      
1370         }                                                                                                
1371                                                                                                          
1372         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1373                 PagedView.INVALID_RESTORE_PAGE);                                                         
1374         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1375             mWorkspace.setRestorePage(currentScreen);                                                    
1376         }                                                                                                
1377                                                                                                          
1378         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1379         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1380                                                                                                          
1381         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1382             mPendingAddInfo.container = pendingAddContainer;                                             
1383             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1384             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1385             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1386             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1387             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1388             AppWidgetProviderInfo info = savedState.getParcelable(                                       
1389                     RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                              
1390             mPendingAddWidgetInfo = info == null ?                                                       
1391                     null : LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                   
1392                                                                                                          
1393             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1394             setWaitingForResult(true);                                                                   
1395             mRestoring = true;                                                                           
1396         }                                                                                                
1397                                                                                                          
1398         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1399                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1400     }                                                                                                    
1401                                                                                                          
1402     /**                                                                                                  
1403      * Finds all the views we need and configure them properly.                                          
1404      */                                                                                                  
1405     private void setupViews() {                                                                          
1406         final DragController dragController = mDragController;                                           
1407                                                                                                          
1408         mLauncherView = findViewById(R.id.launcher);                                                     
1409         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1410         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1411         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1412         mWorkspace.setPageSwitchListener(this);                                                          
1413         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1414                                                                                                          
1415         mLauncherView.setSystemUiVisibility(                                                             
1416                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1417         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1418                                                                                                          
1419         // Setup the drag layer                                                                          
1420         mDragLayer.setup(this, dragController);                                                          
1421                                                                                                          
1422         // Setup the hotseat                                                                             
1423         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1424         if (mHotseat != null) {                                                                          
1425             mHotseat.setOnLongClickListener(this);                                                       
1426         }                                                                                                
1427                                                                                                          
1428         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1429         View widgetButton = findViewById(R.id.widget_button);                                            
1430         widgetButton.setOnClickListener(new OnClickListener() {                                          
1431             @Override                                                                                    
1432             public void onClick(View arg0) {                                                             
1433                 if (!mWorkspace.isSwitchingState()) {                                                    
1434                     onClickAddWidgetButton(arg0);                                                        
1435                 }                                                                                        
1436             }                                                                                            
1437         });                                                                                              
1438         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1439                                                                                                          
1440         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1441         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1442             @Override                                                                                    
1443             public void onClick(View arg0) {                                                             
1444                 if (!mWorkspace.isSwitchingState()) {                                                    
1445                     onClickWallpaperPicker(arg0);                                                        
1446                 }                                                                                        
1447             }                                                                                            
1448         });                                                                                              
1449         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1450                                                                                                          
1451         View settingsButton = findViewById(R.id.settings_button);                                        
1452         if (hasSettings()) {                                                                             
1453             settingsButton.setOnClickListener(new OnClickListener() {                                    
1454                 @Override                                                                                
1455                 public void onClick(View arg0) {                                                         
1456                     if (!mWorkspace.isSwitchingState()) {                                                
1457                         onClickSettingsButton(arg0);                                                     
1458                     }                                                                                    
1459                 }                                                                                        
1460             });                                                                                          
1461             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1462         } else {                                                                                         
1463             settingsButton.setVisibility(View.GONE);                                                     
1464         }                                                                                                
1465                                                                                                          
1466         mOverviewPanel.setAlpha(0f);                                                                     
1467                                                                                                          
1468         // Setup the workspace                                                                           
1469         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1470         mWorkspace.setOnLongClickListener(this);                                                         
1471         mWorkspace.setup(dragController);                                                                
1472         dragController.addDragListener(mWorkspace);                                                      
1473                                                                                                          
1474         // Get the search/delete bar                                                                     
1475         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1476                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1477                                                                                                          
1478         // Setup Apps                                                                                    
1479         mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);                                 
1480         if (isAllAppsSearchOverridden()) {                                                               
1481             mAppsView.hideHeaderBar();                                                                   
1482         }                                                                                                
1483                                                                                                          
1484         // Setup AppsCustomize                                                                           
1485         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                           
1486                                                                                                          
1487         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1488         dragController.setDragScoller(mWorkspace);                                                       
1489         dragController.setScrollView(mDragLayer);                                                        
1490         dragController.setMoveTarget(mWorkspace);                                                        
1491         dragController.addDropTarget(mWorkspace);                                                        
1492         if (mSearchDropTargetBar != null) {                                                              
1493             mSearchDropTargetBar.setup(this, dragController);                                            
1494             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1495         }                                                                                                
1496                                                                                                          
1497         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1498             Log.v(TAG, "adding WeightWatcher");                                                          
1499             mWeightWatcher = new WeightWatcher(this);                                                    
1500             mWeightWatcher.setAlpha(0.5f);                                                               
1501             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1502                     new FrameLayout.LayoutParams(                                                        
1503                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1504                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1505                             Gravity.BOTTOM)                                                              
1506             );                                                                                           
1507                                                                                                          
1508             boolean show = shouldShowWeightWatcher();                                                    
1509             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1510         }                                                                                                
1511     }                                                                                                    
1512                                                                                                          
1513     /**                                                                                                  
1514      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1515      */                                                                                                  
1516     public void setAllAppsButton(View allAppsButton) {                                                   
1517         mAllAppsButton = allAppsButton;                                                                  
1518     }                                                                                                    
1519                                                                                                          
1520     public View getAllAppsButton() {                                                                     
1521         return mAllAppsButton;                                                                           
1522     }                                                                                                    
1523                                                                                                          
1524     /**                                                                                                  
1525      * Creates a view representing a shortcut.                                                           
1526      *                                                                                                   
1527      * @param info The data structure describing the shortcut.                                           
1528      */                                                                                                  
1529     View createShortcut(ShortcutInfo info) {                                                             
1530         return createShortcut((ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);     
1531     }                                                                                                    
1532                                                                                                          
1533     /**                                                                                                  
1534      * Creates a view representing a shortcut inflated from the specified resource.                      
1535      *                                                                                                   
1536      * @param parent The group the shortcut belongs to.                                                  
1537      * @param info The data structure describing the shortcut.                                           
1538      *                                                                                                   
1539      * @return A View inflated from layoutResId.                                                         
1540      */                                                                                                  
1541     public View createShortcut(ViewGroup parent, ShortcutInfo info) {                                    
1542         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(R.layout.app_icon,                  
1543                 parent, false);                                                                          
1544         favorite.applyFromShortcutInfo(info, mIconCache);                                                
1545         favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);                       
1546         favorite.setOnClickListener(this);                                                               
1547         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1548         return favorite;                                                                                 
1549     }                                                                                                    
1550                                                                                                          
1551     /**                                                                                                  
1552      * Add a shortcut to the workspace.                                                                  
1553      *                                                                                                   
1554      * @param data The intent describing the shortcut.                                                   
1555      * @param cellInfo The position on screen where to create the shortcut.                              
1556      */                                                                                                  
1557     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1558             int cellY) {                                                                                 
1559         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1560         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1561         CellLayout layout = getCellLayout(container, screenId);                                          
1562                                                                                                          
1563         ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(this, data);                      
1564         if (info == null) {                                                                              
1565             return;                                                                                      
1566         }                                                                                                
1567         final View view = createShortcut(info);                                                          
1568                                                                                                          
1569         boolean foundCellSpan = false;                                                                   
1570         // First we check if we already know the exact location where we want to add this item.          
1571         if (cellX >= 0 && cellY >= 0) {                                                                  
1572             cellXY[0] = cellX;                                                                           
1573             cellXY[1] = cellY;                                                                           
1574             foundCellSpan = true;                                                                        
1575                                                                                                          
1576             // If appropriate, either create a folder or add to an existing folder                       
1577             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1578                     true, null,null)) {                                                                  
1579                 return;                                                                                  
1580             }                                                                                            
1581             DragObject dragObject = new DragObject();                                                    
1582             dragObject.dragInfo = info;                                                                  
1583             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1584                     true)) {                                                                             
1585                 return;                                                                                  
1586             }                                                                                            
1587         } else if (touchXY != null) {                                                                    
1588             // when dragging and dropping, just find the closest free spot                               
1589             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1590             foundCellSpan = (result != null);                                                            
1591         } else {                                                                                         
1592             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1593         }                                                                                                
1594                                                                                                          
1595         if (!foundCellSpan) {                                                                            
1596             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1597             return;                                                                                      
1598         }                                                                                                
1599                                                                                                          
1600         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1601                                                                                                          
1602         if (!mRestoring) {                                                                               
1603             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1604                     isWorkspaceLocked());                                                                
1605         }                                                                                                
1606     }                                                                                                    
1607                                                                                                          
1608     private int[] getSpanForWidget(ComponentName component, int minWidth, int minHeight) {               
1609         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(this, component, null);              
1610         // We want to account for the extra amount of padding that we are adding to the widget           
1611         // to ensure that it gets the full amount of space that it has requested                         
1612         int requiredWidth = minWidth + padding.left + padding.right;                                     
1613         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1614         return CellLayout.rectToCell(this, requiredWidth, requiredHeight, null);                         
1615     }                                                                                                    
1616                                                                                                          
1617     public int[] getSpanForWidget(AppWidgetProviderInfo info) {                                          
1618         return getSpanForWidget(info.provider, info.minWidth, info.minHeight);                           
1619     }                                                                                                    
1620                                                                                                          
1621     public int[] getMinSpanForWidget(AppWidgetProviderInfo info) {                                       
1622         return getSpanForWidget(info.provider, info.minResizeWidth, info.minResizeHeight);               
1623     }                                                                                                    
1624                                                                                                          
1625     /**                                                                                                  
1626      * Add a widget to the workspace.                                                                    
1627      *                                                                                                   
1628      * @param appWidgetId The app widget id                                                              
1629      */                                                                                                  
1630     @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                     
1631             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1632                                                                                                          
1633         ItemInfo info = mPendingAddInfo;                                                                 
1634         if (appWidgetInfo == null) {                                                                     
1635             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1636                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1637         }                                                                                                
1638                                                                                                          
1639         if (appWidgetInfo.isCustomWidget) {                                                              
1640             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1641         }                                                                                                
1642                                                                                                          
1643         LauncherAppWidgetInfo launcherInfo;                                                              
1644         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1645         launcherInfo.spanX = info.spanX;                                                                 
1646         launcherInfo.spanY = info.spanY;                                                                 
1647         launcherInfo.minSpanX = info.minSpanX;                                                           
1648         launcherInfo.minSpanY = info.minSpanY;                                                           
1649         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1650                                                                                                          
1651         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1652                 container, screenId, info.cellX, info.cellY);                                            
1653                                                                                                          
1654         if (!mRestoring) {                                                                               
1655             if (hostView == null) {                                                                      
1656                 // Perform actual inflation because we're live                                           
1657                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1658                         appWidgetInfo);                                                                  
1659             } else {                                                                                     
1660                 // The AppWidgetHostView has already been inflated and instantiated                      
1661                 launcherInfo.hostView = hostView;                                                        
1662             }                                                                                            
1663             launcherInfo.hostView.setTag(launcherInfo);                                                  
1664             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1665             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1666                                                                                                          
1667             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1668                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1669                                                                                                          
1670             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1671         }                                                                                                
1672         resetAddInfo();                                                                                  
1673     }                                                                                                    
1674                                                                                                          
1675     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1676         @Override                                                                                        
1677         public void onReceive(Context context, Intent intent) {                                          
1678             final String action = intent.getAction();                                                    
1679             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1680                 mUserPresent = false;                                                                    
1681                 mDragLayer.clearAllResizeFrames();                                                       
1682                 updateAutoAdvanceState();                                                                
1683                                                                                                          
1684                 // Reset AllApps to its initial state only if we are not in the middle of                
1685                 // processing a multi-step drop                                                          
1686                 if (mAppsView != null && mWidgetsView != null &&                                         
1687                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1688                     showWorkspace(false);                                                                
1689                 }                                                                                        
1690             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1691                 mUserPresent = true;                                                                     
1692                 updateAutoAdvanceState();                                                                
1693             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1694                 mModel.resetLoadedState(false, true);                                                    
1695                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                       
1696                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1697             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1698                 mModel.resetLoadedState(false, true);                                                    
1699                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                       
1700                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1701                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1702             }                                                                                            
1703         }                                                                                                
1704     };                                                                                                   
1705                                                                                                          
1706     @Override                                                                                            
1707     public void onAttachedToWindow() {                                                                   
1708         super.onAttachedToWindow();                                                                      
1709                                                                                                          
1710         // Listen for broadcasts related to user-presence                                                
1711         final IntentFilter filter = new IntentFilter();                                                  
1712         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1713         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1714         // For handling managed profiles                                                                 
1715         if (ENABLE_DEBUG_INTENTS) {                                                                      
1716             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1717             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1718         }                                                                                                
1719         registerReceiver(mReceiver, filter);                                                             
1720         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1721         setupTransparentSystemBarsForLmp();                                                              
1722         mAttached = true;                                                                                
1723         mVisible = true;                                                                                 
1724     }                                                                                                    
1725                                                                                                          
1726     /**                                                                                                  
1727      * Sets up transparent navigation and status bars in LMP.                                            
1728      * This method is a no-op for other platform versions.                                               
1729      */                                                                                                  
1730     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1731     private void setupTransparentSystemBarsForLmp() {                                                    
1732         if (Utilities.isLmpOrAbove()) {                                                                  
1733             Window window = getWindow();                                                                 
1734             window.getAttributes().systemUiVisibility |=                                                 
1735                     (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                   
1736                             | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                      
1737                             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                               
1738             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1739                     | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                           
1740             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1741             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1742             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1743         }                                                                                                
1744     }                                                                                                    
1745                                                                                                          
1746     @Override                                                                                            
1747     public void onDetachedFromWindow() {                                                                 
1748         super.onDetachedFromWindow();                                                                    
1749         mVisible = false;                                                                                
1750                                                                                                          
1751         if (mAttached) {                                                                                 
1752             unregisterReceiver(mReceiver);                                                               
1753             mAttached = false;                                                                           
1754         }                                                                                                
1755         updateAutoAdvanceState();                                                                        
1756     }                                                                                                    
1757                                                                                                          
1758     public void onWindowVisibilityChanged(int visibility) {                                              
1759         mVisible = visibility == View.VISIBLE;                                                           
1760         updateAutoAdvanceState();                                                                        
1761         // The following code used to be in onResume, but it turns out onResume is called when           
1762         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1763         // is a more appropriate event to handle                                                         
1764         if (mVisible) {                                                                                  
1765             if (!mWorkspaceLoading) {                                                                    
1766                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1767                 // We want to let Launcher draw itself at least once before we force it to build         
1768                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1769                 // apps is nice and speedy.                                                              
1770                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1771                     private boolean mStarted = false;                                                    
1772                     public void onDraw() {                                                               
1773                         if (mStarted) return;                                                            
1774                         mStarted = true;                                                                 
1775                         // We delay the layer building a bit in order to give                            
1776                         // other message processing a time to run.  In particular                        
1777                         // this avoids a delay in hiding the IME if it was                               
1778                         // currently shown, because doing that may involve                               
1779                         // some communication back with the app.                                         
1780                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1781                         final ViewTreeObserver.OnDrawListener listener = this;                           
1782                         mWorkspace.post(new Runnable() {                                                 
1783                                 public void run() {                                                      
1784                                     if (mWorkspace != null &&                                            
1785                                             mWorkspace.getViewTreeObserver() != null) {                  
1786                                         mWorkspace.getViewTreeObserver().                                
1787                                                 removeOnDrawListener(listener);                          
1788                                     }                                                                    
1789                                 }                                                                        
1790                             });                                                                          
1791                         return;                                                                          
1792                     }                                                                                    
1793                 });                                                                                      
1794             }                                                                                            
1795             clearTypedText();                                                                            
1796         }                                                                                                
1797     }                                                                                                    
1798                                                                                                          
1799     @Thunk void sendAdvanceMessage(long delay) {                                                         
1800         mHandler.removeMessages(ADVANCE_MSG);                                                            
1801         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1802         mHandler.sendMessageDelayed(msg, delay);                                                         
1803         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1804     }                                                                                                    
1805                                                                                                          
1806     @Thunk void updateAutoAdvanceState() {                                                               
1807         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1808         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1809             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1810             if (autoAdvanceRunning) {                                                                    
1811                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1812                 sendAdvanceMessage(delay);                                                               
1813             } else {                                                                                     
1814                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1815                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1816                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1817                 }                                                                                        
1818                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1819                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1820             }                                                                                            
1821         }                                                                                                
1822     }                                                                                                    
1823                                                                                                          
1824     private final Handler mHandler = new Handler() {                                                     
1825         @Override                                                                                        
1826         public void handleMessage(Message msg) {                                                         
1827             if (msg.what == ADVANCE_MSG) {                                                               
1828                 int i = 0;                                                                               
1829                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1830                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1831                     final int delay = mAdvanceStagger * i;                                               
1832                     if (v instanceof Advanceable) {                                                      
1833                        postDelayed(new Runnable() {                                                      
1834                            public void run() {                                                           
1835                                ((Advanceable) v).advance();                                              
1836                            }                                                                             
1837                        }, delay);                                                                        
1838                     }                                                                                    
1839                     i++;                                                                                 
1840                 }                                                                                        
1841                 sendAdvanceMessage(mAdvanceInterval);                                                    
1842             }                                                                                            
1843         }                                                                                                
1844     };                                                                                                   
1845                                                                                                          
1846     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1847         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1848         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1849         if (v instanceof Advanceable) {                                                                  
1850             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1851             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1852             updateAutoAdvanceState();                                                                    
1853         }                                                                                                
1854     }                                                                                                    
1855                                                                                                          
1856     void removeWidgetToAutoAdvance(View hostView) {                                                      
1857         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1858             mWidgetsToAdvance.remove(hostView);                                                          
1859             updateAutoAdvanceState();                                                                    
1860         }                                                                                                
1861     }                                                                                                    
1862                                                                                                          
1863     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1864         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1865         launcherInfo.hostView = null;                                                                    
1866     }                                                                                                    
1867                                                                                                          
1868     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1869         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1870         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1871     }                                                                                                    
1872                                                                                                          
1873     public DragLayer getDragLayer() {                                                                    
1874         return mDragLayer;                                                                               
1875     }                                                                                                    
1876                                                                                                          
1877     public AllAppsContainerView getAppsView() {                                                          
1878         return mAppsView;                                                                                
1879     }                                                                                                    
1880                                                                                                          
1881     public WidgetsContainerView getWidgetsView() {                                                       
1882         return mWidgetsView;                                                                             
1883     }                                                                                                    
1884                                                                                                          
1885     public Workspace getWorkspace() {                                                                    
1886         return mWorkspace;                                                                               
1887     }                                                                                                    
1888                                                                                                          
1889     public Hotseat getHotseat() {                                                                        
1890         return mHotseat;                                                                                 
1891     }                                                                                                    
1892                                                                                                          
1893     public ViewGroup getOverviewPanel() {                                                                
1894         return mOverviewPanel;                                                                           
1895     }                                                                                                    
1896                                                                                                          
1897     public SearchDropTargetBar getSearchBar() {                                                          
1898         return mSearchDropTargetBar;                                                                     
1899     }                                                                                                    
1900                                                                                                          
1901     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1902         return mAppWidgetHost;                                                                           
1903     }                                                                                                    
1904                                                                                                          
1905     public LauncherModel getModel() {                                                                    
1906         return mModel;                                                                                   
1907     }                                                                                                    
1908                                                                                                          
1909     protected SharedPreferences getSharedPrefs() {                                                       
1910         return mSharedPrefs;                                                                             
1911     }                                                                                                    
1912                                                                                                          
1913     public DeviceProfile getDeviceProfile() {                                                            
1914         return mDeviceProfile;                                                                           
1915     }                                                                                                    
1916                                                                                                          
1917     public void closeSystemDialogs() {                                                                   
1918         getWindow().closeAllPanels();                                                                    
1919                                                                                                          
1920         // Whatever we were doing is hereby canceled.                                                    
1921         setWaitingForResult(false);                                                                      
1922     }                                                                                                    
1923                                                                                                          
1924     @Override                                                                                            
1925     protected void onNewIntent(Intent intent) {                                                          
1926         long startTime = 0;                                                                              
1927         if (DEBUG_RESUME_TIME) {                                                                         
1928             startTime = System.currentTimeMillis();                                                      
1929         }                                                                                                
1930         super.onNewIntent(intent);                                                                       
1931                                                                                                          
1932         // Close the menu                                                                                
1933         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1934             // also will cancel mWaitingForResult.                                                       
1935             closeSystemDialogs();                                                                        
1936                                                                                                          
1937             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1938                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1939                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1940                                                                                                          
1941             if (mWorkspace == null) {                                                                    
1942                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1943                 return;                                                                                  
1944             }                                                                                            
1945             Folder openFolder = mWorkspace.getOpenFolder();                                              
1946             // In all these cases, only animate if we're already on home                                 
1947             mWorkspace.exitWidgetResizeMode();                                                           
1948                                                                                                          
1949             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1950                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1951             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1952                     openFolder == null && moveToDefaultScreen) {                                         
1953                 mWorkspace.moveToDefaultScreen(true);                                                    
1954             }                                                                                            
1955                                                                                                          
1956             closeFolder();                                                                               
1957             exitSpringLoadedDragMode();                                                                  
1958                                                                                                          
1959             // If we are already on home, then just animate back to the workspace,                       
1960             // otherwise, just wait until onResume to set the state back to Workspace                    
1961             if (alreadyOnHome) {                                                                         
1962                 showWorkspace(true);                                                                     
1963             } else {                                                                                     
1964                 mOnResumeState = State.WORKSPACE;                                                        
1965             }                                                                                            
1966                                                                                                          
1967             final View v = getWindow().peekDecorView();                                                  
1968             if (v != null && v.getWindowToken() != null) {                                               
1969                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1970                         INPUT_METHOD_SERVICE);                                                           
1971                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1972             }                                                                                            
1973                                                                                                          
1974             // Reset the apps view                                                                       
1975             if (!alreadyOnHome && mAppsView != null) {                                                   
1976                 mAppsView.scrollToTop();                                                                 
1977             }                                                                                            
1978                                                                                                          
1979             // Reset the widgets view                                                                    
1980             if (!alreadyOnHome && mWidgetsView != null) {                                                
1981                 mWidgetsView.scrollToTop();                                                              
1982             }                                                                                            
1983                                                                                                          
1984             if (mLauncherCallbacks != null) {                                                            
1985                 mLauncherCallbacks.onHomeIntent();                                                       
1986             }                                                                                            
1987         }                                                                                                
1988                                                                                                          
1989         if (DEBUG_RESUME_TIME) {                                                                         
1990             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1991         }                                                                                                
1992                                                                                                          
1993         if (mLauncherCallbacks != null) {                                                                
1994             mLauncherCallbacks.onNewIntent(intent);                                                      
1995         }                                                                                                
1996     }                                                                                                    
1997                                                                                                          
1998     @Override                                                                                            
1999     public void onRestoreInstanceState(Bundle state) {                                                   
2000         super.onRestoreInstanceState(state);                                                             
2001         for (int page: mSynchronouslyBoundPages) {                                                       
2002             mWorkspace.restoreInstanceStateForChild(page);                                               
2003         }                                                                                                
2004     }                                                                                                    
2005                                                                                                          
2006     @Override                                                                                            
2007     protected void onSaveInstanceState(Bundle outState) {                                                
2008         if (mWorkspace.getChildCount() > 0) {                                                            
2009             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
2010                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
2011         }                                                                                                
2012         super.onSaveInstanceState(outState);                                                             
2013                                                                                                          
2014         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
2015         // We close any open folder since it will not be re-opened, and we need to make sure             
2016         // this state is reflected.                                                                      
2017         closeFolder();                                                                                   
2018                                                                                                          
2019         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
2020                 mWaitingForResult) {                                                                     
2021             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
2022             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
2023             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
2024             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
2025             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
2026             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
2027             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
2028             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2029         }                                                                                                
2030                                                                                                          
2031         // Save the current widgets tray?                                                                
2032         // TODO(hyunyoungs)                                                                              
2033         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2034                                                                                                          
2035         if (mLauncherCallbacks != null) {                                                                
2036             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2037         }                                                                                                
2038     }                                                                                                    
2039                                                                                                          
2040     @Override                                                                                            
2041     public void onDestroy() {                                                                            
2042         super.onDestroy();                                                                               
2043                                                                                                          
2044         // Remove all pending runnables                                                                  
2045         mHandler.removeMessages(ADVANCE_MSG);                                                            
2046         mHandler.removeMessages(0);                                                                      
2047         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2048                                                                                                          
2049         // Stop callbacks from LauncherModel                                                             
2050         LauncherAppState app = (LauncherAppState.getInstance());                                         
2051                                                                                                          
2052         // It's possible to receive onDestroy after a new Launcher activity has                          
2053         // been created. In this case, don't interfere with the new Launcher.                            
2054         if (mModel.isCurrentCallbacks(this)) {                                                           
2055             mModel.stopLoader();                                                                         
2056             app.setLauncher(null);                                                                       
2057         }                                                                                                
2058                                                                                                          
2059         try {                                                                                            
2060             mAppWidgetHost.stopListening();                                                              
2061         } catch (NullPointerException ex) {                                                              
2062             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2063         }                                                                                                
2064         mAppWidgetHost = null;                                                                           
2065                                                                                                          
2066         mWidgetsToAdvance.clear();                                                                       
2067                                                                                                          
2068         TextKeyListener.getInstance().release();                                                         
2069                                                                                                          
2070         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2071         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2072                                                                                                          
2073         mDragLayer.clearAllResizeFrames();                                                               
2074         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2075         mWorkspace.removeAllWorkspaceScreens();                                                          
2076         mWorkspace = null;                                                                               
2077         mDragController = null;                                                                          
2078                                                                                                          
2079         LauncherAnimUtils.onDestroyActivity();                                                           
2080                                                                                                          
2081         if (mLauncherCallbacks != null) {                                                                
2082             mLauncherCallbacks.onDestroy();                                                              
2083         }                                                                                                
2084     }                                                                                                    
2085                                                                                                          
2086     public DragController getDragController() {                                                          
2087         return mDragController;                                                                          
2088     }                                                                                                    
2089                                                                                                          
2090     @Override                                                                                            
2091     public void startActivityForResult(Intent intent, int requestCode) {                                 
2092         onStartForResult(requestCode);                                                                   
2093         super.startActivityForResult(intent, requestCode);                                               
2094     }                                                                                                    
2095                                                                                                          
2096     @Override                                                                                            
2097     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2098             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2099         onStartForResult(requestCode);                                                                   
2100         try {                                                                                            
2101             super.startIntentSenderForResult(intent, requestCode,                                        
2102                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2103         } catch (IntentSender.SendIntentException e) {                                                   
2104             throw new ActivityNotFoundException();                                                       
2105         }                                                                                                
2106     }                                                                                                    
2107                                                                                                          
2108     private void onStartForResult(int requestCode) {                                                     
2109         if (requestCode >= 0) {                                                                          
2110             setWaitingForResult(true);                                                                   
2111         }                                                                                                
2112     }                                                                                                    
2113                                                                                                          
2114     /**                                                                                                  
2115      * Indicates that we want global search for this activity by setting the globalSearch                
2116      * argument for {@link #startSearch} to true.                                                        
2117      */                                                                                                  
2118     @Override                                                                                            
2119     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2120             Bundle appSearchData, boolean globalSearch) {                                                
2121                                                                                                          
2122         if (initialQuery == null) {                                                                      
2123             // Use any text typed in the launcher as the initial query                                   
2124             initialQuery = getTypedText();                                                               
2125         }                                                                                                
2126         if (appSearchData == null) {                                                                     
2127             appSearchData = new Bundle();                                                                
2128             appSearchData.putString("source", "launcher-search");                                        
2129         }                                                                                                
2130         Rect sourceBounds = new Rect();                                                                  
2131         if (mSearchDropTargetBar != null) {                                                              
2132             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2133         }                                                                                                
2134                                                                                                          
2135         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2136                 appSearchData, sourceBounds);                                                            
2137         if (clearTextImmediately) {                                                                      
2138             clearTypedText();                                                                            
2139         }                                                                                                
2140                                                                                                          
2141         // We need to show the workspace after starting the search                                       
2142         showWorkspace(true);                                                                             
2143     }                                                                                                    
2144                                                                                                          
2145     /**                                                                                                  
2146      * Start a text search.                                                                              
2147      *                                                                                                   
2148      * @return {@code true} if the search will start immediately, so any further keypresses              
2149      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2150      * to buffer keypresses.                                                                             
2151      */                                                                                                  
2152     public boolean startSearch(String initialQuery,                                                      
2153             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2154         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2155             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2156                     sourceBounds);                                                                       
2157         }                                                                                                
2158                                                                                                          
2159         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2160                 appSearchData, sourceBounds);                                                            
2161         return false;                                                                                    
2162     }                                                                                                    
2163                                                                                                          
2164     /**                                                                                                  
2165      * Starts the global search activity. This code is a copied from SearchManager                       
2166      */                                                                                                  
2167     private void startGlobalSearch(String initialQuery,                                                  
2168             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2169         final SearchManager searchManager =                                                              
2170             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2171         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2172         if (globalSearchActivity == null) {                                                              
2173             Log.w(TAG, "No global search activity found.");                                              
2174             return;                                                                                      
2175         }                                                                                                
2176         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2177         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2178         intent.setComponent(globalSearchActivity);                                                       
2179         // Make sure that we have a Bundle to put source in                                              
2180         if (appSearchData == null) {                                                                     
2181             appSearchData = new Bundle();                                                                
2182         } else {                                                                                         
2183             appSearchData = new Bundle(appSearchData);                                                   
2184         }                                                                                                
2185         // Set source to package name of app that starts global search if not set already.               
2186         if (!appSearchData.containsKey("source")) {                                                      
2187             appSearchData.putString("source", getPackageName());                                         
2188         }                                                                                                
2189         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2190         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2191             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2192         }                                                                                                
2193         if (selectInitialQuery) {                                                                        
2194             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2195         }                                                                                                
2196         intent.setSourceBounds(sourceBounds);                                                            
2197         try {                                                                                            
2198             startActivity(intent);                                                                       
2199         } catch (ActivityNotFoundException ex) {                                                         
2200             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2201         }                                                                                                
2202     }                                                                                                    
2203                                                                                                          
2204     public boolean isOnCustomContent() {                                                                 
2205         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2206     }                                                                                                    
2207                                                                                                          
2208     @Override                                                                                            
2209     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2210         super.onPrepareOptionsMenu(menu);                                                                
2211         if (!isOnCustomContent()) {                                                                      
2212             // Close any open folders                                                                    
2213             closeFolder();                                                                               
2214             // Stop resizing any widgets                                                                 
2215             mWorkspace.exitWidgetResizeMode();                                                           
2216             if (!mWorkspace.isInOverviewMode()) {                                                        
2217                 // Show the overview mode                                                                
2218                 showOverviewMode(true);                                                                  
2219             } else {                                                                                     
2220                 showWorkspace(true);                                                                     
2221             }                                                                                            
2222         }                                                                                                
2223         if (mLauncherCallbacks != null) {                                                                
2224             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2225         }                                                                                                
2226                                                                                                          
2227         return false;                                                                                    
2228     }                                                                                                    
2229                                                                                                          
2230     @Override                                                                                            
2231     public boolean onSearchRequested() {                                                                 
2232         startSearch(null, false, null, true);                                                            
2233         // Use a custom animation for launching search                                                   
2234         return true;                                                                                     
2235     }                                                                                                    
2236                                                                                                          
2237     public boolean isWorkspaceLocked() {                                                                 
2238         return mWorkspaceLoading || mWaitingForResult;                                                   
2239     }                                                                                                    
2240                                                                                                          
2241     public boolean isWorkspaceLoading() {                                                                
2242         return mWorkspaceLoading;                                                                        
2243     }                                                                                                    
2244                                                                                                          
2245     private void setWorkspaceLoading(boolean value) {                                                    
2246         boolean isLocked = isWorkspaceLocked();                                                          
2247         mWorkspaceLoading = value;                                                                       
2248         if (isLocked != isWorkspaceLocked()) {                                                           
2249             onWorkspaceLockedChanged();                                                                  
2250         }                                                                                                
2251     }                                                                                                    
2252                                                                                                          
2253     private void setWaitingForResult(boolean value) {                                                    
2254         boolean isLocked = isWorkspaceLocked();                                                          
2255         mWaitingForResult = value;                                                                       
2256         if (isLocked != isWorkspaceLocked()) {                                                           
2257             onWorkspaceLockedChanged();                                                                  
2258         }                                                                                                
2259     }                                                                                                    
2260                                                                                                          
2261     protected void onWorkspaceLockedChanged() {                                                          
2262         if (mLauncherCallbacks != null) {                                                                
2263             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2264         }                                                                                                
2265     }                                                                                                    
2266                                                                                                          
2267     private void resetAddInfo() {                                                                        
2268         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2269         mPendingAddInfo.screenId = -1;                                                                   
2270         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2271         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2272         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2273         mPendingAddInfo.dropPos = null;                                                                  
2274     }                                                                                                    
2275                                                                                                          
2276     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2277             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2278         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2279     }                                                                                                    
2280                                                                                                          
2281     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2282             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2283             int delay) {                                                                                 
2284         if (appWidgetInfo.configure != null) {                                                           
2285             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2286             mPendingAddWidgetId = appWidgetId;                                                           
2287                                                                                                          
2288             // Launch over to configure widget, if needed                                                
2289             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2290                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2291                                                                                                          
2292         } else {                                                                                         
2293             // Otherwise just add it                                                                     
2294             Runnable onComplete = new Runnable() {                                                       
2295                 @Override                                                                                
2296                 public void run() {                                                                      
2297                     // Exit spring loaded mode if necessary after adding the widget                      
2298                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2299                             null);                                                                       
2300                 }                                                                                        
2301             };                                                                                           
2302             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2303                     appWidgetInfo);                                                                      
2304             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2305         }                                                                                                
2306     }                                                                                                    
2307                                                                                                          
2308     protected void moveToCustomContentScreen(boolean animate) {                                          
2309         // Close any folders that may be open.                                                           
2310         closeFolder();                                                                                   
2311         mWorkspace.moveToCustomContentScreen(animate);                                                   
2312     }                                                                                                    
2313                                                                                                          
2314     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2315             int[] cell, int spanX, int spanY) {                                                          
2316         switch (info.itemType) {                                                                         
2317             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2318             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2319                 int span[] = new int[2];                                                                 
2320                 span[0] = spanX;                                                                         
2321                 span[1] = spanY;                                                                         
2322                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2323                         container, screenId, cell, span);                                                
2324                 break;                                                                                   
2325             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2326                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2327                 break;                                                                                   
2328             default:                                                                                     
2329                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2330             }                                                                                            
2331     }                                                                                                    
2332                                                                                                          
2333     /**                                                                                                  
2334      * Process a shortcut drop.                                                                          
2335      *                                                                                                   
2336      * @param componentName The name of the component                                                    
2337      * @param screenId The ID of the screen where it should be added                                     
2338      * @param cell The cell it should be added to, optional                                              
2339      */                                                                                                  
2340     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2341             int[] cell) {                                                                                
2342         resetAddInfo();                                                                                  
2343         mPendingAddInfo.container = container;                                                           
2344         mPendingAddInfo.screenId = screenId;                                                             
2345         mPendingAddInfo.dropPos = null;                                                                  
2346                                                                                                          
2347         if (cell != null) {                                                                              
2348             mPendingAddInfo.cellX = cell[0];                                                             
2349             mPendingAddInfo.cellY = cell[1];                                                             
2350         }                                                                                                
2351                                                                                                          
2352         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2353         createShortcutIntent.setComponent(componentName);                                                
2354         processShortcut(createShortcutIntent);                                                           
2355     }                                                                                                    
2356                                                                                                          
2357     /**                                                                                                  
2358      * Process a widget drop.                                                                            
2359      *                                                                                                   
2360      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2361      * @param screenId The ID of the screen where it should be added                                     
2362      * @param cell The cell it should be added to, optional                                              
2363      */                                                                                                  
2364     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2365             int[] cell, int[] span) {                                                                    
2366         resetAddInfo();                                                                                  
2367         mPendingAddInfo.container = info.container = container;                                          
2368         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2369         mPendingAddInfo.dropPos = null;                                                                  
2370         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2371         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2372                                                                                                          
2373         if (cell != null) {                                                                              
2374             mPendingAddInfo.cellX = cell[0];                                                             
2375             mPendingAddInfo.cellY = cell[1];                                                             
2376         }                                                                                                
2377         if (span != null) {                                                                              
2378             mPendingAddInfo.spanX = span[0];                                                             
2379             mPendingAddInfo.spanY = span[1];                                                             
2380         }                                                                                                
2381                                                                                                          
2382         AppWidgetHostView hostView = info.boundWidget;                                                   
2383         int appWidgetId;                                                                                 
2384         if (hostView != null) {                                                                          
2385             appWidgetId = hostView.getAppWidgetId();                                                     
2386             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2387         } else {                                                                                         
2388             // In this case, we either need to start an activity to get permission to bind               
2389             // the widget, or we need to start an activity to configure the widget, or both.             
2390             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2391             Bundle options = info.bindOptions;                                                           
2392                                                                                                          
2393             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2394                     appWidgetId, info.info, options);                                                    
2395             if (success) {                                                                               
2396                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2397             } else {                                                                                     
2398                 mPendingAddWidgetInfo = info.info;                                                       
2399                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2400                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2401                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2402                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2403                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2404                 // TODO: we need to make sure that this accounts for the options bundle.                 
2405                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2406                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2407             }                                                                                            
2408         }                                                                                                
2409     }                                                                                                    
2410                                                                                                          
2411     void processShortcut(Intent intent) {                                                                
2412         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2413     }                                                                                                    
2414                                                                                                          
2415     void processWallpaper(Intent intent) {                                                               
2416         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2417     }                                                                                                    
2418                                                                                                          
2419     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2420             int cellY) {                                                                                 
2421         final FolderInfo folderInfo = new FolderInfo();                                                  
2422         folderInfo.title = getText(R.string.folder_name);                                                
2423                                                                                                          
2424         // Update the model                                                                              
2425         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                  
2426                 cellX, cellY);                                                                           
2427         sFolders.put(folderInfo.id, folderInfo);                                                         
2428                                                                                                          
2429         // Create the view                                                                               
2430         FolderIcon newFolder =                                                                           
2431             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2432         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2433                 isWorkspaceLocked());                                                                    
2434         // Force measure the new folder icon                                                             
2435         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2436         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2437         return newFolder;                                                                                
2438     }                                                                                                    
2439                                                                                                          
2440     void removeFolder(FolderInfo folder) {                                                               
2441         sFolders.remove(folder.id);                                                                      
2442     }                                                                                                    
2443                                                                                                          
2444     /**                                                                                                  
2445      * Registers various content observers. The current implementation registers                         
2446      * only a favorites observer to keep track of the favorites applications.                            
2447      */                                                                                                  
2448     private void registerContentObservers() {                                                            
2449         ContentResolver resolver = getContentResolver();                                                 
2450         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2451                 true, mWidgetObserver);                                                                  
2452     }                                                                                                    
2453                                                                                                          
2454     @Override                                                                                            
2455     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2456         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2457             switch (event.getKeyCode()) {                                                                
2458                 case KeyEvent.KEYCODE_HOME:                                                              
2459                     return true;                                                                         
2460                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2461                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2462                         dumpState();                                                                     
2463                         return true;                                                                     
2464                     }                                                                                    
2465                     break;                                                                               
2466             }                                                                                            
2467         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2468             switch (event.getKeyCode()) {                                                                
2469                 case KeyEvent.KEYCODE_HOME:                                                              
2470                     return true;                                                                         
2471             }                                                                                            
2472         }                                                                                                
2473                                                                                                          
2474         return super.dispatchKeyEvent(event);                                                            
2475     }                                                                                                    
2476                                                                                                          
2477     @Override                                                                                            
2478     public void onBackPressed() {                                                                        
2479         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2480             return;                                                                                      
2481         }                                                                                                
2482                                                                                                          
2483         LauncherAccessibilityDelegate delegate =                                                         
2484                 LauncherAppState.getInstance().getAccessibilityDelegate();                               
2485         if (delegate != null && delegate.onBackPressed()) {                                              
2486             return;                                                                                      
2487         }                                                                                                
2488                                                                                                          
2489         if (isAppsViewVisible()) {                                                                       
2490             showWorkspace(true);                                                                         
2491         } else if (isWidgetsViewVisible())  {                                                            
2492             showOverviewMode(true);                                                                      
2493         } else if (mWorkspace.isInOverviewMode()) {                                                      
2494             showWorkspace(true);                                                                         
2495         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2496             Folder openFolder = mWorkspace.getOpenFolder();                                              
2497             if (openFolder.isEditingName()) {                                                            
2498                 openFolder.dismissEditingName();                                                         
2499             } else {                                                                                     
2500                 closeFolder();                                                                           
2501             }                                                                                            
2502         } else {                                                                                         
2503             mWorkspace.exitWidgetResizeMode();                                                           
2504                                                                                                          
2505             // Back button is a no-op here, but give at least some feedback for the button press         
2506             mWorkspace.showOutlinesTemporarily();                                                        
2507         }                                                                                                
2508     }                                                                                                    
2509                                                                                                          
2510     /**                                                                                                  
2511      * Re-listen when widgets are reset.                                                                 
2512      */                                                                                                  
2513     @Thunk void onAppWidgetReset() {                                                                     
2514         if (mAppWidgetHost != null) {                                                                    
2515             mAppWidgetHost.startListening();                                                             
2516         }                                                                                                
2517     }                                                                                                    
2518                                                                                                          
2519     /**                                                                                                  
2520      * Launches the intent referred by the clicked shortcut.                                             
2521      *                                                                                                   
2522      * @param v The view representing the clicked shortcut.                                              
2523      */                                                                                                  
2524     public void onClick(View v) {                                                                        
2525         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2526         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2527         if (v.getWindowToken() == null) {                                                                
2528             return;                                                                                      
2529         }                                                                                                
2530                                                                                                          
2531         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2532             return;                                                                                      
2533         }                                                                                                
2534                                                                                                          
2535         if (v instanceof Workspace) {                                                                    
2536             if (mWorkspace.isInOverviewMode()) {                                                         
2537                 showWorkspace(true);                                                                     
2538             }                                                                                            
2539             return;                                                                                      
2540         }                                                                                                
2541                                                                                                          
2542         if (v instanceof CellLayout) {                                                                   
2543             if (mWorkspace.isInOverviewMode()) {                                                         
2544                 showWorkspace(mWorkspace.indexOfChild(v), true);                                         
2545             }                                                                                            
2546         }                                                                                                
2547                                                                                                          
2548         Object tag = v.getTag();                                                                         
2549         if (tag instanceof ShortcutInfo) {                                                               
2550             onClickAppShortcut(v);                                                                       
2551         } else if (tag instanceof FolderInfo) {                                                          
2552             if (v instanceof FolderIcon) {                                                               
2553                 onClickFolderIcon(v);                                                                    
2554             }                                                                                            
2555         } else if (v == mAllAppsButton) {                                                                
2556             onClickAllAppsButton(v);                                                                     
2557         } else if (tag instanceof AppInfo) {                                                             
2558             startAppShortcutOrInfoActivity(v);                                                           
2559         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2560             if (v instanceof PendingAppWidgetHostView) {                                                 
2561                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2562             }                                                                                            
2563         }                                                                                                
2564     }                                                                                                    
2565                                                                                                          
2566     public void onClickPagedViewIcon(View v) {                                                           
2567         startAppShortcutOrInfoActivity(v);                                                               
2568         if (mLauncherCallbacks != null) {                                                                
2569             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2570         }                                                                                                
2571     }                                                                                                    
2572                                                                                                          
2573     @SuppressLint("ClickableViewAccessibility")                                                          
2574     public boolean onTouch(View v, MotionEvent event) {                                                  
2575         return false;                                                                                    
2576     }                                                                                                    
2577                                                                                                          
2578     /**                                                                                                  
2579      * Event handler for the app widget view which has not fully restored.                               
2580      */                                                                                                  
2581     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2582         if (mIsSafeModeEnabled) {                                                                        
2583             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2584             return;                                                                                      
2585         }                                                                                                
2586                                                                                                          
2587         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2588         if (v.isReadyForClickSetup()) {                                                                  
2589             int widgetId = info.appWidgetId;                                                             
2590             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2591             if (appWidgetInfo != null) {                                                                 
2592                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2593                         this, appWidgetInfo);                                                            
2594                 mPendingAddInfo.copyFrom(info);                                                          
2595                 mPendingAddWidgetId = widgetId;                                                          
2596                                                                                                          
2597                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2598                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2599             }                                                                                            
2600         } else if (info.installProgress < 0) {                                                           
2601             // The install has not been queued                                                           
2602             final String packageName = info.providerName.getPackageName();                               
2603             showBrokenAppInstallDialog(packageName,                                                      
2604                 new DialogInterface.OnClickListener() {                                                  
2605                     public void onClick(DialogInterface dialog, int id) {                                
2606                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2607                     }                                                                                    
2608                 });                                                                                      
2609         } else {                                                                                         
2610             // Download has started.                                                                     
2611             final String packageName = info.providerName.getPackageName();                               
2612             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2613         }                                                                                                
2614     }                                                                                                    
2615                                                                                                          
2616     /**                                                                                                  
2617      * Event handler for the "grid" button that appears on the home screen, which                        
2618      * enters all apps mode.                                                                             
2619      *                                                                                                   
2620      * @param v The view that was clicked.                                                               
2621      */                                                                                                  
2622     protected void onClickAllAppsButton(View v) {                                                        
2623         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2624         if (isAppsViewVisible()) {                                                                       
2625             showWorkspace(true);                                                                         
2626         } else {                                                                                         
2627             // Try and refresh the set of predicted apps before we enter launcher                        
2628             showAppsView(true /* animated */, false /* resetListToTop */,                                
2629                     true /* updatePredictedApps */);                                                     
2630         }                                                                                                
2631     }                                                                                                    
2632                                                                                                          
2633     private void showBrokenAppInstallDialog(final String packageName,                                    
2634             DialogInterface.OnClickListener onSearchClickListener) {                                     
2635         new AlertDialog.Builder(this)                                                                    
2636             .setTitle(R.string.abandoned_promises_title)                                                 
2637             .setMessage(R.string.abandoned_promise_explanation)                                          
2638             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2639             .setNeutralButton(R.string.abandoned_clean_this,                                             
2640                 new DialogInterface.OnClickListener() {                                                  
2641                     public void onClick(DialogInterface dialog, int id) {                                
2642                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2643                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2644                     }                                                                                    
2645                 })                                                                                       
2646             .create().show();                                                                            
2647         return;                                                                                          
2648     }                                                                                                    
2649                                                                                                          
2650     /**                                                                                                  
2651      * Event handler for an app shortcut click.                                                          
2652      *                                                                                                   
2653      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2654      */                                                                                                  
2655     protected void onClickAppShortcut(final View v) {                                                    
2656         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2657         Object tag = v.getTag();                                                                         
2658         if (!(tag instanceof ShortcutInfo)) {                                                            
2659             throw new IllegalArgumentException("Input must be a Shortcut");                              
2660         }                                                                                                
2661                                                                                                          
2662         // Open shortcut                                                                                 
2663         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2664                                                                                                          
2665         if (shortcut.isDisabled != 0) {                                                                  
2666             int error = R.string.activity_not_available;                                                 
2667             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2668                 error = R.string.safemode_shortcut_error;                                                
2669             }                                                                                            
2670             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2671             return;                                                                                      
2672         }                                                                                                
2673                                                                                                          
2674         final Intent intent = shortcut.intent;                                                           
2675                                                                                                          
2676         // Check for special shortcuts                                                                   
2677         if (intent.getComponent() != null) {                                                             
2678             final String shortcutClass = intent.getComponent().getClassName();                           
2679                                                                                                          
2680             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2681                 MemoryDumpActivity.startDump(this);                                                      
2682                 return;                                                                                  
2683             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2684                 toggleShowWeightWatcher();                                                               
2685                 return;                                                                                  
2686             }                                                                                            
2687         }                                                                                                
2688                                                                                                          
2689         // Check for abandoned promise                                                                   
2690         if ((v instanceof BubbleTextView)                                                                
2691                 && shortcut.isPromise()                                                                  
2692                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2693             showBrokenAppInstallDialog(                                                                  
2694                     shortcut.getTargetComponent().getPackageName(),                                      
2695                     new DialogInterface.OnClickListener() {                                              
2696                         public void onClick(DialogInterface dialog, int id) {                            
2697                             startAppShortcutOrInfoActivity(v);                                           
2698                         }                                                                                
2699                     });                                                                                  
2700             return;                                                                                      
2701         }                                                                                                
2702                                                                                                          
2703         // Start activities                                                                              
2704         startAppShortcutOrInfoActivity(v);                                                               
2705                                                                                                          
2706         if (mLauncherCallbacks != null) {                                                                
2707             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2708         }                                                                                                
2709     }                                                                                                    
2710                                                                                                          
2711     @Thunk void startAppShortcutOrInfoActivity(View v) {                                                 
2712         Object tag = v.getTag();                                                                         
2713         final ShortcutInfo shortcut;                                                                     
2714         final Intent intent;                                                                             
2715         if (tag instanceof ShortcutInfo) {                                                               
2716             shortcut = (ShortcutInfo) tag;                                                               
2717             intent = shortcut.intent;                                                                    
2718             int[] pos = new int[2];                                                                      
2719             v.getLocationOnScreen(pos);                                                                  
2720             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2721                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2722                                                                                                          
2723         } else if (tag instanceof AppInfo) {                                                             
2724             shortcut = null;                                                                             
2725             intent = ((AppInfo) tag).intent;                                                             
2726         } else {                                                                                         
2727             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2728         }                                                                                                
2729                                                                                                          
2730         boolean success = startActivitySafely(v, intent, tag);                                           
2731         mStats.recordLaunch(intent, shortcut);                                                           
2732                                                                                                          
2733         if (success && v instanceof BubbleTextView) {                                                    
2734             mWaitingForResume = (BubbleTextView) v;                                                      
2735             mWaitingForResume.setStayPressed(true);                                                      
2736         }                                                                                                
2737     }                                                                                                    
2738                                                                                                          
2739     /**                                                                                                  
2740      * Event handler for a folder icon click.                                                            
2741      *                                                                                                   
2742      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2743      */                                                                                                  
2744     protected void onClickFolderIcon(View v) {                                                           
2745         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2746         if (!(v instanceof FolderIcon)){                                                                 
2747             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2748         }                                                                                                
2749                                                                                                          
2750         FolderIcon folderIcon = (FolderIcon) v;                                                          
2751         final FolderInfo info = folderIcon.getFolderInfo();                                              
2752         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2753                                                                                                          
2754         // If the folder info reports that the associated folder is open, then verify that               
2755         // it is actually opened. There have been a few instances where this gets out of sync.           
2756         if (info.opened && openFolder == null) {                                                         
2757             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2758                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2759             info.opened = false;                                                                         
2760         }                                                                                                
2761                                                                                                          
2762         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2763             // Close any open folder                                                                     
2764             closeFolder();                                                                               
2765             // Open the requested folder                                                                 
2766             openFolder(folderIcon);                                                                      
2767         } else {                                                                                         
2768             // Find the open folder...                                                                   
2769             int folderScreen;                                                                            
2770             if (openFolder != null) {                                                                    
2771                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2772                 // .. and close it                                                                       
2773                 closeFolder(openFolder);                                                                 
2774                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2775                     // Close any folder open on the current screen                                       
2776                     closeFolder();                                                                       
2777                     // Pull the folder onto this screen                                                  
2778                     openFolder(folderIcon);                                                              
2779                 }                                                                                        
2780             }                                                                                            
2781         }                                                                                                
2782                                                                                                          
2783         if (mLauncherCallbacks != null) {                                                                
2784             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2785         }                                                                                                
2786     }                                                                                                    
2787                                                                                                          
2788     /**                                                                                                  
2789      * Event handler for the (Add) Widgets button that appears after a long press                        
2790      * on the home screen.                                                                               
2791      */                                                                                                  
2792     protected void onClickAddWidgetButton(View view) {                                                   
2793         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2794         if (mIsSafeModeEnabled) {                                                                        
2795             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2796         } else {                                                                                         
2797             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2798             if (mLauncherCallbacks != null) {                                                            
2799                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2800             }                                                                                            
2801         }                                                                                                
2802     }                                                                                                    
2803                                                                                                          
2804     /**                                                                                                  
2805      * Event handler for the wallpaper picker button that appears after a long press                     
2806      * on the home screen.                                                                               
2807      */                                                                                                  
2808     protected void onClickWallpaperPicker(View v) {                                                      
2809         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2810         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),     
2811                 REQUEST_PICK_WALLPAPER);                                                                 
2812                                                                                                          
2813         if (mLauncherCallbacks != null) {                                                                
2814             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2815         }                                                                                                
2816     }                                                                                                    
2817                                                                                                          
2818     /**                                                                                                  
2819      * Event handler for a click on the settings button that appears after a long press                  
2820      * on the home screen.                                                                               
2821      */                                                                                                  
2822     protected void onClickSettingsButton(View v) {                                                       
2823         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2824         if (mLauncherCallbacks != null) {                                                                
2825             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2826         }                                                                                                
2827     }                                                                                                    
2828                                                                                                          
2829     public void onTouchDownAllAppsButton(View v) {                                                       
2830         // Provide the same haptic feedback that the system offers for virtual keys.                     
2831         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2832     }                                                                                                    
2833                                                                                                          
2834     public void performHapticFeedbackOnTouchDown(View v) {                                               
2835         // Provide the same haptic feedback that the system offers for virtual keys.                     
2836         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2837     }                                                                                                    
2838                                                                                                          
2839     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2840         if (mHapticFeedbackTouchListener == null) {                                                      
2841             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2842                 @SuppressLint("ClickableViewAccessibility")                                              
2843                 @Override                                                                                
2844                 public boolean onTouch(View v, MotionEvent event) {                                      
2845                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2846                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2847                     }                                                                                    
2848                     return false;                                                                        
2849                 }                                                                                        
2850             };                                                                                           
2851         }                                                                                                
2852         return mHapticFeedbackTouchListener;                                                             
2853     }                                                                                                    
2854                                                                                                          
2855     public void onDragStarted(View view) {                                                               
2856         if (isOnCustomContent()) {                                                                       
2857             // Custom content screen doesn't participate in drag and drop. If on custom                  
2858             // content screen, move to default.                                                          
2859             moveWorkspaceToDefaultScreen();                                                              
2860         }                                                                                                
2861                                                                                                          
2862         if (mLauncherCallbacks != null) {                                                                
2863             mLauncherCallbacks.onDragStarted(view);                                                      
2864         }                                                                                                
2865     }                                                                                                    
2866                                                                                                          
2867     /**                                                                                                  
2868      * Called when the user stops interacting with the launcher.                                         
2869      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2870      */                                                                                                  
2871     protected void onInteractionEnd() {                                                                  
2872         if (mLauncherCallbacks != null) {                                                                
2873             mLauncherCallbacks.onInteractionEnd();                                                       
2874         }                                                                                                
2875     }                                                                                                    
2876                                                                                                          
2877     /**                                                                                                  
2878      * Called when the user starts interacting with the launcher.                                        
2879      * The possible interactions are:                                                                    
2880      *  - open all apps                                                                                  
2881      *  - reorder an app shortcut, or a widget                                                           
2882      *  - open the overview mode.                                                                        
2883      * This is a good time to stop doing things that only make sense                                     
2884      * when the user is on the homescreen and not doing housekeeping.                                    
2885      */                                                                                                  
2886     protected void onInteractionBegin() {                                                                
2887         if (mLauncherCallbacks != null) {                                                                
2888             mLauncherCallbacks.onInteractionBegin();                                                     
2889         }                                                                                                
2890     }                                                                                                    
2891                                                                                                          
2892     /** Updates the interaction state. */                                                                
2893     public void updateInteraction(Workspace.State fromState, Workspace.State toState) {                  
2894         // Only update the interacting state if we are transitioning to/from a view with an              
2895         // overlay                                                                                       
2896         boolean fromStateWithOverlay;                                                                    
2897         boolean toStateWithOverlay;                                                                      
2898         if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
2899             fromStateWithOverlay = fromState != Workspace.State.NORMAL;                                  
2900             toStateWithOverlay = toState != Workspace.State.NORMAL;                                      
2901         } else {                                                                                         
2902             fromStateWithOverlay = fromState != Workspace.State.NORMAL &&                                
2903                     fromState != Workspace.State.NORMAL_HIDDEN;                                          
2904             toStateWithOverlay = toState != Workspace.State.NORMAL &&                                    
2905                     toState != Workspace.State.NORMAL_HIDDEN;                                            
2906         }                                                                                                
2907         if (toStateWithOverlay) {                                                                        
2908             onInteractionBegin();                                                                        
2909         } else if (fromStateWithOverlay) {                                                               
2910             onInteractionEnd();                                                                          
2911         }                                                                                                
2912     }                                                                                                    
2913                                                                                                          
2914     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2915         try {                                                                                            
2916             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2917             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2918         } catch (SecurityException e) {                                                                  
2919             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2920             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2921         } catch (ActivityNotFoundException e) {                                                          
2922             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2923             Log.e(TAG, "Unable to launch settings");                                                     
2924         }                                                                                                
2925     }                                                                                                    
2926                                                                                                          
2927     // returns true if the activity was started                                                          
2928     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2929             UserHandleCompat user) {                                                                     
2930         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2931             // System applications cannot be installed. For now, show a toast explaining that.           
2932             // We may give them the option of disabling apps this way.                                   
2933             int messageId = R.string.uninstall_system_app_text;                                          
2934             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2935             return false;                                                                                
2936         } else {                                                                                         
2937             String packageName = componentName.getPackageName();                                         
2938             String className = componentName.getClassName();                                             
2939             Intent intent = new Intent(                                                                  
2940                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2941             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2942                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2943             if (user != null) {                                                                          
2944                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2945             }                                                                                            
2946             startActivity(intent);                                                                       
2947             return true;                                                                                 
2948         }                                                                                                
2949     }                                                                                                    
2950                                                                                                          
2951     boolean startActivity(View v, Intent intent, Object tag) {                                           
2952         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2953         try {                                                                                            
2954             // Only launch using the new animation if the shortcut has not opted out (this is a          
2955             // private contract between launcher and may be ignored in the future).                      
2956             boolean useLaunchAnimation = (v != null) &&                                                  
2957                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2958             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2959             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2960                                                                                                          
2961             UserHandleCompat user = null;                                                                
2962             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2963                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2964                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2965             }                                                                                            
2966                                                                                                          
2967             Bundle optsBundle = null;                                                                    
2968 <<<<<<< GitAnalyzerPlus_ours                                                                             
2969             if (useLaunchAnimation) {                                                                    
2970                 ActivityOptions opts = null;                                                             
2971                 if (sClipRevealMethod != null) {                                                         
2972                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2973                     int left = 0, top = 0;                                                               
2974                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2975                     if (v instanceof TextView) {                                                         
2976                         // Launch from center of icon, not entire view                                   
2977                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2978                         if (icon != null) {                                                              
2979                             Rect bounds = icon.getBounds();                                              
2980                             left = (width - bounds.width()) / 2;                                         
2981                             top = v.getPaddingTop();                                                     
2982                             width = bounds.width();                                                      
2983                             height = bounds.height();                                                    
2984                         }                                                                                
2985                     }                                                                                    
2986                     try {                                                                                
2987                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2988                                 left, top, width, height);                                               
2989                     } catch (IllegalAccessException e) {                                                 
2990                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2991                         sClipRevealMethod = null;                                                        
2992                     } catch (InvocationTargetException e) {                                              
2993                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2994                         sClipRevealMethod = null;                                                        
2995                     }                                                                                    
2996                 }                                                                                        
2997                 if (opts == null && !Utilities.isLmpOrAbove()) {                                         
2998                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                 
2999                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
3000                 }                                                                                        
3001                 optsBundle = opts != null ? opts.toBundle() : null;                                      
3002 ||||||| GitAnalyzerPlus_base                                                                             
3003             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
3004                 // On pre-L devices, we use the scale up transition.                                     
3005                 // Otherwise we use system default.                                                      
3006                 ActivityOptions opts =                                                                   
3007                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3008                 optsBundle = opts.toBundle();                                                            
3009             }                                                                                            
3010                                                                                                          
3011             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3012                 // Could be launching some bookkeeping activity                                          
3013                 startActivity(intent, optsBundle);                                                       
3014             } else {                                                                                     
3015                 // TODO Component can be null when shortcuts are supported for secondary user            
3016                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3017                         intent.getSourceBounds(), optsBundle);                                           
3018             }                                                                                            
3019             return true;                                                                                 
3020         } catch (SecurityException e) {                                                                  
3021             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3022             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3023                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3024                     "or use the exported attribute for this activity. "                                  
3025                     + "tag="+ tag + " intent=" + intent, e);                                             
3026         }                                                                                                
3027         return false;                                                                                    
3028     }                                                                                                    
3029                                                                                                          
3030     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
3031         boolean success = false;                                                                         
3032         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
3033             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
3034             return false;                                                                                
3035         }                                                                                                
3036         try {                                                                                            
3037             success = startActivity(v, intent, tag);                                                     
3038         } catch (ActivityNotFoundException e) {                                                          
3039             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3040             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
3041         }                                                                                                
3042         return success;                                                                                  
3043     }                                                                                                    
3044                                                                                                          
3045     /**                                                                                                  
3046      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
3047      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
3048      */                                                                                                  
3049     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3050         final int width = fi.getMeasuredWidth();                                                         
3051         final int height = fi.getMeasuredHeight();                                                       
3052                                                                                                          
3053         // Lazy load ImageView, Bitmap and Canvas                                                        
3054         if (mFolderIconImageView == null) {                                                              
3055             mFolderIconImageView = new ImageView(this);                                                  
3056         }                                                                                                
3057         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3058                 mFolderIconBitmap.getHeight() != height) {                                               
3059             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3060 =======                                                                                                  
3061             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
3062                 // On pre-L devices, we use the scale up transition.                                     
3063                 ActivityOptions opts =                                                                   
3064                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3065                 optsBundle = opts.toBundle();                                                            
3066             } else if (useLaunchAnimation && Utilities.isLmpMr1()) {                                     
3067                 // On L-MR1 devices, we use custom slide up animation without a delay                    
3068                 // On L devices, we use the system default slide up.                                     
3069                 ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,                         
3070                         R.anim.task_open_enter, R.anim.no_anim);                                         
3071                 optsBundle = opts.toBundle();                                                            
3072 >>>>>>> GitAnalyzerPlus_theirs                                                                           
3073             }                                                                                            
3074                                                                                                          
3075             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3076                 // Could be launching some bookkeeping activity                                          
3077                 startActivity(intent, optsBundle);                                                       
3078             } else {                                                                                     
3079                 // TODO Component can be null when shortcuts are supported for secondary user            
3080                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3081                         intent.getSourceBounds(), optsBundle);                                           
3082             }                                                                                            
3083             return true;                                                                                 
3084         } catch (SecurityException e) {                                                                  
3085             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3086             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3087                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3088                     "or use the exported attribute for this activity. "                                  
3089                     + "tag="+ tag + " intent=" + intent, e);                                             
3090         }                                                                                                
3091         return false;                                                                                    
3092     }                                                                                                    
3093                                                                                                          
3094     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
3095         boolean success = false;                                                                         
3096         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
3097             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
3098             return false;                                                                                
3099         }                                                                                                
3100         try {                                                                                            
3101             success = startActivity(v, intent, tag);                                                     
3102         } catch (ActivityNotFoundException e) {                                                          
3103             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3104             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
3105         }                                                                                                
3106         return success;                                                                                  
3107     }                                                                                                    
3108                                                                                                          
3109     /**                                                                                                  
3110      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
3111      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
3112      */                                                                                                  
3113     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3114         final int width = fi.getMeasuredWidth();                                                         
3115         final int height = fi.getMeasuredHeight();                                                       
3116                                                                                                          
3117         // Lazy load ImageView, Bitmap and Canvas                                                        
3118         if (mFolderIconImageView == null) {                                                              
3119             mFolderIconImageView = new ImageView(this);                                                  
3120         }                                                                                                
3121         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3122                 mFolderIconBitmap.getHeight() != height) {                                               
3123             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3124             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3125         }                                                                                                
3126                                                                                                          
3127         DragLayer.LayoutParams lp;                                                                       
3128         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3129             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3130         } else {                                                                                         
3131             lp = new DragLayer.LayoutParams(width, height);                                              
3132         }                                                                                                
3133                                                                                                          
3134         // The layout from which the folder is being opened may be scaled, adjust the starting           
3135         // view size by this scale factor.                                                               
3136         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3137         lp.customPosition = true;                                                                        
3138         lp.x = mRectForFolderAnimation.left;                                                             
3139         lp.y = mRectForFolderAnimation.top;                                                              
3140         lp.width = (int) (scale * width);                                                                
3141         lp.height = (int) (scale * height);                                                              
3142                                                                                                          
3143         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3144         fi.draw(mFolderIconCanvas);                                                                      
3145         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3146         if (fi.getFolder() != null) {                                                                    
3147             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3148             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3149         }                                                                                                
3150         // Just in case this image view is still in the drag layer from a previous animation,            
3151         // we remove it and re-add it.                                                                   
3152         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3153             mDragLayer.removeView(mFolderIconImageView);                                                 
3154         }                                                                                                
3155         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3156         if (fi.getFolder() != null) {                                                                    
3157             fi.getFolder().bringToFront();                                                               
3158         }                                                                                                
3159     }                                                                                                    
3160                                                                                                          
3161     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3162         if (fi == null) return;                                                                          
3163         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3164         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3165         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3166                                                                                                          
3167         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3168         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3169             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3170             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3171             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3172         }                                                                                                
3173                                                                                                          
3174         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3175         copyFolderIconToImage(fi);                                                                       
3176         fi.setVisibility(View.INVISIBLE);                                                                
3177                                                                                                          
3178         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3179                 scaleX, scaleY);                                                                         
3180         if (Utilities.isLmpOrAbove()) {                                                                  
3181             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3182         }                                                                                                
3183         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3184         oa.start();                                                                                      
3185     }                                                                                                    
3186                                                                                                          
3187     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3188         if (fi == null) return;                                                                          
3189         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3190         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3191         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3192                                                                                                          
3193         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3194                                                                                                          
3195         // We remove and re-draw the FolderIcon in-case it has changed                                   
3196         mDragLayer.removeView(mFolderIconImageView);                                                     
3197         copyFolderIconToImage(fi);                                                                       
3198         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3199                 scaleX, scaleY);                                                                         
3200         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3201         oa.addListener(new AnimatorListenerAdapter() {                                                   
3202             @Override                                                                                    
3203             public void onAnimationEnd(Animator animation) {                                             
3204                 if (cl != null) {                                                                        
3205                     cl.clearFolderLeaveBehind();                                                         
3206                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3207                     mDragLayer.removeView(mFolderIconImageView);                                         
3208                     fi.setVisibility(View.VISIBLE);                                                      
3209                 }                                                                                        
3210             }                                                                                            
3211         });                                                                                              
3212         oa.start();                                                                                      
3213     }                                                                                                    
3214                                                                                                          
3215     /**                                                                                                  
3216      * Opens the user folder described by the specified tag. The opening of the folder                   
3217      * is animated relative to the specified View. If the View is null, no animation                     
3218      * is played.                                                                                        
3219      *                                                                                                   
3220      * @param folderInfo The FolderInfo describing the folder to open.                                   
3221      */                                                                                                  
3222     public void openFolder(FolderIcon folderIcon) {                                                      
3223         Folder folder = folderIcon.getFolder();                                                          
3224         Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                      
3225         if (openFolder != null && openFolder != folder) {                                                
3226             // Close any open folder before opening a folder.                                            
3227             closeFolder();                                                                               
3228         }                                                                                                
3229                                                                                                          
3230         FolderInfo info = folder.mInfo;                                                                  
3231                                                                                                          
3232         info.opened = true;                                                                              
3233                                                                                                          
3234         // While the folder is open, the position of the icon cannot change.                             
3235         ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                     
3236                                                                                                          
3237         // Just verify that the folder hasn't already been added to the DragLayer.                       
3238         // There was a one-off crash where the folder had a parent already.                              
3239         if (folder.getParent() == null) {                                                                
3240             mDragLayer.addView(folder);                                                                  
3241             mDragController.addDropTarget((DropTarget) folder);                                          
3242         } else {                                                                                         
3243             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3244                     folder.getParent() + ").");                                                          
3245         }                                                                                                
3246         folder.animateOpen();                                                                            
3247         growAndFadeOutFolderIcon(folderIcon);                                                            
3248                                                                                                          
3249         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3250         // the workspace items                                                                           
3251         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3252         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3253     }                                                                                                    
3254                                                                                                          
3255     public void closeFolder() {                                                                          
3256         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3257         if (folder != null) {                                                                            
3258             if (folder.isEditingName()) {                                                                
3259                 folder.dismissEditingName();                                                             
3260             }                                                                                            
3261             closeFolder(folder);                                                                         
3262         }                                                                                                
3263     }                                                                                                    
3264                                                                                                          
3265     public void closeFolder(Folder folder) {                                                             
3266         folder.getInfo().opened = false;                                                                 
3267                                                                                                          
3268         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3269         if (parent != null) {                                                                            
3270             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3271             shrinkAndFadeInFolderIcon(fi);                                                               
3272             if (fi != null) {                                                                            
3273                 ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                      
3274             }                                                                                            
3275         }                                                                                                
3276         folder.animateClosed();                                                                          
3277                                                                                                          
3278         // Notify the accessibility manager that this folder "window" has disappeard and no              
3279         // longer occludeds the workspace items                                                          
3280         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3281     }                                                                                                    
3282                                                                                                          
3283     public boolean onLongClick(View v) {                                                                 
3284         if (!isDraggingEnabled()) return false;                                                          
3285         if (isWorkspaceLocked()) return false;                                                           
3286         if (mState != State.WORKSPACE) return false;                                                     
3287                                                                                                          
3288         if (v instanceof Workspace) {                                                                    
3289             if (!mWorkspace.isInOverviewMode()) {                                                        
3290                 if (!mWorkspace.isTouchActive()) {                                                       
3291                     showOverviewMode(true);                                                              
3292                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3293                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3294                     return true;                                                                         
3295                 } else {                                                                                 
3296                     return false;                                                                        
3297                 }                                                                                        
3298             } else {                                                                                     
3299                 return false;                                                                            
3300             }                                                                                            
3301         }                                                                                                
3302                                                                                                          
3303         CellLayout.CellInfo longClickCellInfo = null;                                                    
3304         View itemUnderLongClick = null;                                                                  
3305         if (v.getTag() instanceof ItemInfo) {                                                            
3306             ItemInfo info = (ItemInfo) v.getTag();                                                       
3307             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3308             itemUnderLongClick = longClickCellInfo.cell;                                                 
3309             resetAddInfo();                                                                              
3310         }                                                                                                
3311                                                                                                          
3312         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3313         // on hotseat items.                                                                             
3314         final boolean inHotseat = isHotseatLayout(v);                                                    
3315         if (!mDragController.isDragging()) {                                                             
3316             if (itemUnderLongClick == null) {                                                            
3317                 // User long pressed on empty space                                                      
3318                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3319                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3320                 if (mWorkspace.isInOverviewMode()) {                                                     
3321                     mWorkspace.startReordering(v);                                                       
3322                 } else {                                                                                 
3323                     showOverviewMode(true);                                                              
3324                 }                                                                                        
3325             } else {                                                                                     
3326                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3327                         mHotseat.getOrderInHotseat(                                                      
3328                                 longClickCellInfo.cellX,                                                 
3329                                 longClickCellInfo.cellY));                                               
3330                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3331                     // User long pressed on an item                                                      
3332                     mWorkspace.startDrag(longClickCellInfo);                                             
3333                 }                                                                                        
3334             }                                                                                            
3335         }                                                                                                
3336         return true;                                                                                     
3337     }                                                                                                    
3338                                                                                                          
3339     boolean isHotseatLayout(View layout) {                                                               
3340         return mHotseat != null && layout != null &&                                                     
3341                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3342     }                                                                                                    
3343                                                                                                          
3344     /**                                                                                                  
3345      * Returns the CellLayout of the specified container at the specified screen.                        
3346      */                                                                                                  
3347     public CellLayout getCellLayout(long container, long screenId) {                                     
3348         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3349             if (mHotseat != null) {                                                                      
3350                 return mHotseat.getLayout();                                                             
3351             } else {                                                                                     
3352                 return null;                                                                             
3353             }                                                                                            
3354         } else {                                                                                         
3355             return mWorkspace.getScreenWithId(screenId);                                                 
3356         }                                                                                                
3357     }                                                                                                    
3358                                                                                                          
3359     /**                                                                                                  
3360      * For overridden classes.                                                                           
3361      */                                                                                                  
3362     public boolean isAllAppsVisible() {                                                                  
3363         return isAppsViewVisible();                                                                      
3364     }                                                                                                    
3365                                                                                                          
3366     public boolean isAppsViewVisible() {                                                                 
3367         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3368     }                                                                                                    
3369                                                                                                          
3370     public boolean isWidgetsViewVisible() {                                                              
3371         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3372     }                                                                                                    
3373                                                                                                          
3374     private void setWorkspaceBackground(int background) {                                                
3375         switch (background) {                                                                            
3376             case WORKSPACE_BACKGROUND_TRANSPARENT:                                                       
3377                 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));                 
3378                 break;                                                                                   
3379             case WORKSPACE_BACKGROUND_BLACK:                                                             
3380                 getWindow().setBackgroundDrawable(null);                                                 
3381                 break;                                                                                   
3382             default:                                                                                     
3383                 getWindow().setBackgroundDrawable(mWorkspaceBackgroundDrawable);                         
3384         }                                                                                                
3385     }                                                                                                    
3386                                                                                                          
3387     protected void changeWallpaperVisiblity(boolean visible) {                                           
3388         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3389         int curflags = getWindow().getAttributes().flags                                                 
3390                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3391         if (wpflags != curflags) {                                                                       
3392             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3393         }                                                                                                
3394         setWorkspaceBackground(visible ? WORKSPACE_BACKGROUND_GRADIENT : WORKSPACE_BACKGROUND_BLACK);    
3395     }                                                                                                    
3396                                                                                                          
3397     @Override                                                                                            
3398     public void onTrimMemory(int level) {                                                                
3399         super.onTrimMemory(level);                                                                       
3400         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3401             // The widget preview db can result in holding onto over                                     
3402             // 3MB of memory for caching which isn't necessary.                                          
3403             SQLiteDatabase.releaseMemory();                                                              
3404                                                                                                          
3405             // This clears all widget bitmaps from the widget tray                                       
3406             // TODO(hyunyoungs)                                                                          
3407         }                                                                                                
3408         if (mLauncherCallbacks != null) {                                                                
3409             mLauncherCallbacks.onTrimMemory(level);                                                      
3410         }                                                                                                
3411     }                                                                                                    
3412                                                                                                          
3413     @Override                                                                                            
3414     public void onStateTransitionHideSearchBar() {                                                       
3415         // Hide the search bar                                                                           
3416         if (mSearchDropTargetBar != null) {                                                              
3417             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3418         }                                                                                                
3419     }                                                                                                    
3420                                                                                                          
3421     public void showWorkspace(boolean animated) {                                                        
3422         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null,          
3423                 true);                                                                                   
3424     }                                                                                                    
3425                                                                                                          
3426     public void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                           
3427         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                
3428                 onCompleteRunnable, true);                                                               
3429     }                                                                                                    
3430                                                                                                          
3431     protected void showWorkspace(int snapToPage, boolean animated) {                                     
3432         showWorkspace(snapToPage, animated, null, true);                                                 
3433     }                                                                                                    
3434                                                                                                          
3435     void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable,                    
3436             boolean notifyLauncherCallbacks) {                                                           
3437         boolean changed = mState != State.WORKSPACE ||                                                   
3438                 mWorkspace.getState() != Workspace.State.NORMAL;                                         
3439         if (changed) {                                                                                   
3440             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3441             mWorkspace.setVisibility(View.VISIBLE);                                                      
3442             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3443                     snapToPage, animated, onCompleteRunnable);                                           
3444                                                                                                          
3445             // Show the search bar (only animate if we were showing the drop target bar in spring        
3446             // loaded mode)                                                                              
3447             if (mSearchDropTargetBar != null) {                                                          
3448                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3449             }                                                                                            
3450                                                                                                          
3451             // Set focus to the AppsCustomize button                                                     
3452             if (mAllAppsButton != null) {                                                                
3453                 mAllAppsButton.requestFocus();                                                           
3454             }                                                                                            
3455         }                                                                                                
3456                                                                                                          
3457         // Change the state *after* we've called all the transition code                                 
3458         mState = State.WORKSPACE;                                                                        
3459                                                                                                          
3460         // Resume the auto-advance of widgets                                                            
3461         mUserPresent = true;                                                                             
3462         updateAutoAdvanceState();                                                                        
3463                                                                                                          
3464         if (changed) {                                                                                   
3465             // Send an accessibility event to announce the context change                                
3466             getWindow().getDecorView()                                                                   
3467                     .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);               
3468             if (notifyLauncherCallbacks) {                                                               
3469                 // Dismiss all apps when the workspace is shown                                          
3470                 if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {       
3471                     mLauncherCallbacks.onAllAppsHidden();                                                
3472                 }                                                                                        
3473             }                                                                                            
3474         }                                                                                                
3475     }                                                                                                    
3476                                                                                                          
3477     void showOverviewMode(boolean animated) {                                                            
3478         mWorkspace.setVisibility(View.VISIBLE);                                                          
3479         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3480                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                      
3481                 null /* onCompleteRunnable */);                                                          
3482         mState = State.WORKSPACE;                                                                        
3483     }                                                                                                    
3484                                                                                                          
3485     /**                                                                                                  
3486      * Shows the apps view.                                                                              
3487      */                                                                                                  
3488     void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps) {           
3489         if (resetListToTop) {                                                                            
3490             mAppsView.scrollToTop();                                                                     
3491         }                                                                                                
3492         if (updatePredictedApps) {                                                                       
3493             tryAndUpdatePredictedApps();                                                                 
3494         }                                                                                                
3495         showAppsOrWidgets(animated, State.APPS);                                                         
3496     }                                                                                                    
3497                                                                                                          
3498     /**                                                                                                  
3499      * Shows the widgets view.                                                                           
3500      */                                                                                                  
3501     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3502         if (LOGD) Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);     
3503         if (resetPageToZero) {                                                                           
3504             mWidgetsView.scrollToTop();                                                                  
3505         }                                                                                                
3506         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3507                                                                                                          
3508         mWidgetsView.post(new Runnable() {                                                               
3509             @Override                                                                                    
3510             public void run() {                                                                          
3511                 mWidgetsView.requestFocus();                                                             
3512             }                                                                                            
3513         });                                                                                              
3514     }                                                                                                    
3515                                                                                                          
3516     /**                                                                                                  
3517      * Sets up the transition to show the apps/widgets view.                                             
3518      *                                                                                                   
3519      * @return whether the current from and to state allowed this operation                              
3520      */                                                                                                  
3521     // TODO: calling method should use the return value so that when {@code false} is returned           
3522     // the workspace transition doesn't fall into invalid state.                                         
3523     private boolean showAppsOrWidgets(boolean animated, State toState) {                                 
3524         if (mState != State.WORKSPACE &&  mState != State.APPS_SPRING_LOADED &&                          
3525                 mState != State.WIDGETS_SPRING_LOADED) {                                                 
3526             return false;                                                                                
3527         }                                                                                                
3528         if (toState != State.APPS && toState != State.WIDGETS) {                                         
3529             return false;                                                                                
3530         }                                                                                                
3531                                                                                                          
3532         if (toState == State.APPS) {                                                                     
3533             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3534             if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {           
3535                 mLauncherCallbacks.onAllAppsShown();                                                     
3536             }                                                                                            
3537         } else {                                                                                         
3538             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3539         }                                                                                                
3540                                                                                                          
3541         // Change the state *after* we've called all the transition code                                 
3542         mState = toState;                                                                                
3543                                                                                                          
3544         // Pause the auto-advance of widgets until we are out of AllApps                                 
3545         mUserPresent = false;                                                                            
3546         updateAutoAdvanceState();                                                                        
3547         closeFolder();                                                                                   
3548                                                                                                          
3549         // Send an accessibility event to announce the context change                                    
3550         getWindow().getDecorView()                                                                       
3551                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3552         return true;                                                                                     
3553     }                                                                                                    
3554                                                                                                          
3555     /**                                                                                                  
3556      * Updates the workspace and interaction state on state change, and return the animation to this     
3557      * new state.                                                                                        
3558      */                                                                                                  
3559     public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, int toPage,              
3560             boolean animated, HashMap<View, Integer> layerViews) {                                       
3561         Workspace.State fromState = mWorkspace.getState();                                               
3562         Animator anim = mWorkspace.setStateWithAnimation(toState, toPage, animated, layerViews);         
3563         updateInteraction(fromState, toState);                                                           
3564         return anim;                                                                                     
3565     }                                                                                                    
3566                                                                                                          
3567     public void enterSpringLoadedDragMode() {                                                            
3568         if (LOGD) Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", mState.name()));      
3569         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3570                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3571             return;                                                                                      
3572         }                                                                                                
3573                                                                                                          
3574         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3575                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true /* animated */,           
3576                 null /* onCompleteRunnable */);                                                          
3577         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3578     }                                                                                                    
3579                                                                                                          
3580     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                 
3581             final Runnable onCompleteRunnable) {                                                         
3582         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3583                                                                                                          
3584         if (successfulDrop) {                                                                            
3585             // We need to trigger all apps hidden to notify search to update itself before the           
3586             // delayed call to showWorkspace below                                                       
3587             if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {           
3588                 mLauncherCallbacks.onAllAppsHidden();                                                    
3589             }                                                                                            
3590         }                                                                                                
3591                                                                                                          
3592         mHandler.postDelayed(new Runnable() {                                                            
3593             @Override                                                                                    
3594             public void run() {                                                                          
3595                 if (successfulDrop) {                                                                    
3596                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3597                     //                                                                                   
3598                     // Before we show workspace, hide all apps again because                             
3599                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3600                     // clean up our state transition functions                                           
3601                     mWidgetsView.setVisibility(View.GONE);                                               
3602                     showWorkspace(true, onCompleteRunnable);                                             
3603                 } else {                                                                                 
3604                     exitSpringLoadedDragMode();                                                          
3605                 }                                                                                        
3606             }                                                                                            
3607         }, delay);                                                                                       
3608     }                                                                                                    
3609                                                                                                          
3610     void exitSpringLoadedDragMode() {                                                                    
3611         if (mState == State.APPS_SPRING_LOADED) {                                                        
3612             showAppsView(true /* animated */, false /* resetListToTop */,                                
3613                     false /* updatePredictedApps */);                                                    
3614         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3615             showWidgetsView(true, false);                                                                
3616         }                                                                                                
3617     }                                                                                                    
3618                                                                                                          
3619     /**                                                                                                  
3620      * Updates the set of predicted apps if it hasn't been updated since the last time Launcher was      
3621      * resumed.                                                                                          
3622      */                                                                                                  
3623     private void tryAndUpdatePredictedApps() {                                                           
3624         if (mLauncherCallbacks != null) {                                                                
3625             List<ComponentName> apps = mLauncherCallbacks.getPredictedApps();                            
3626             if (!apps.isEmpty()) {                                                                       
3627                 mAppsView.setPredictedApps(apps);                                                        
3628             }                                                                                            
3629         }                                                                                                
3630     }                                                                                                    
3631                                                                                                          
3632     void lockAllApps() {                                                                                 
3633         // TODO                                                                                          
3634     }                                                                                                    
3635                                                                                                          
3636     void unlockAllApps() {                                                                               
3637         // TODO                                                                                          
3638     }                                                                                                    
3639                                                                                                          
3640     protected void disableVoiceButtonProxy(boolean disable) {                                            
3641         // NO-OP                                                                                         
3642     }                                                                                                    
3643                                                                                                          
3644     public View getOrCreateQsbBar() {                                                                    
3645         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3646             return mLauncherCallbacks.getQsbBar();                                                       
3647         }                                                                                                
3648                                                                                                          
3649         if (mQsb == null) {                                                                              
3650             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3651             if (searchProvider == null) {                                                                
3652                 return null;                                                                             
3653             }                                                                                            
3654                                                                                                          
3655             Bundle opts = new Bundle();                                                                  
3656             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3657                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3658                                                                                                          
3659             SharedPreferences sp = getSharedPreferences(                                                 
3660                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3661             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3662             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3663             if (!searchProvider.provider.flattenToString().equals(                                       
3664                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3665                     || (widgetInfo == null)                                                              
3666                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3667                 // A valid widget is not already bound.                                                  
3668                 if (widgetId > -1) {                                                                     
3669                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3670                     widgetId = -1;                                                                       
3671                 }                                                                                        
3672                                                                                                          
3673                 // Try to bind a new widget                                                              
3674                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3675                                                                                                          
3676                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3677                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3678                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3679                     widgetId = -1;                                                                       
3680                 }                                                                                        
3681                                                                                                          
3682                 sp.edit()                                                                                
3683                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3684                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3685                     .commit();                                                                           
3686             }                                                                                            
3687                                                                                                          
3688             if (widgetId != -1) {                                                                        
3689                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3690                 mQsb.updateAppWidgetOptions(opts);                                                       
3691                 mQsb.setPadding(0, 0, 0, 0);                                                             
3692                 mSearchDropTargetBar.addView(mQsb);                                                      
3693                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3694             }                                                                                            
3695         }                                                                                                
3696         return mQsb;                                                                                     
3697     }                                                                                                    
3698                                                                                                          
3699     private void reinflateQSBIfNecessary() {                                                             
3700         if (mQsb instanceof LauncherAppWidgetHostView &&                                                 
3701                 ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                              
3702             mSearchDropTargetBar.removeView(mQsb);                                                       
3703             mQsb = null;                                                                                 
3704             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3705         }                                                                                                
3706     }                                                                                                    
3707                                                                                                          
3708     @Override                                                                                            
3709     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3710         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3711         final List<CharSequence> text = event.getText();                                                 
3712         text.clear();                                                                                    
3713         // Populate event with a fake title based on the current state.                                  
3714         if (mState == State.APPS) {                                                                      
3715             text.add(getString(R.string.all_apps_button_label));                                         
3716         } else if (mState == State.WIDGETS) {                                                            
3717             text.add(getString(R.string.widget_button_text));                                            
3718         } else {                                                                                         
3719             text.add(getString(R.string.all_apps_home_button_label));                                    
3720         }                                                                                                
3721         return result;                                                                                   
3722     }                                                                                                    
3723                                                                                                          
3724     /**                                                                                                  
3725      * Receives notifications when system dialogs are to be closed.                                      
3726      */                                                                                                  
3727     @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                            
3728         @Override                                                                                        
3729         public void onReceive(Context context, Intent intent) {                                          
3730             closeSystemDialogs();                                                                        
3731         }                                                                                                
3732     }                                                                                                    
3733                                                                                                          
3734     /**                                                                                                  
3735      * Receives notifications whenever the appwidgets are reset.                                         
3736      */                                                                                                  
3737     private class AppWidgetResetObserver extends ContentObserver {                                       
3738         public AppWidgetResetObserver() {                                                                
3739             super(new Handler());                                                                        
3740         }                                                                                                
3741                                                                                                          
3742         @Override                                                                                        
3743         public void onChange(boolean selfChange) {                                                       
3744             onAppWidgetReset();                                                                          
3745         }                                                                                                
3746     }                                                                                                    
3747                                                                                                          
3748     /**                                                                                                  
3749      * If the activity is currently paused, signal that we need to run the passed Runnable               
3750      * in onResume.                                                                                      
3751      *                                                                                                   
3752      * This needs to be called from incoming places where resources might have been loaded               
3753      * while the activity is paused. That is because the Configuration (e.g., rotation)  might be        
3754      * wrong when we're not running, and if the activity comes back to what the configuration was        
3755      * when we were paused, activity is not restarted.                                                   
3756      *                                                                                                   
3757      * Implementation of the method from LauncherModel.Callbacks.                                        
3758      *                                                                                                   
3759      * @return {@code true} if we are currently paused. The caller might be able to skip some work       
3760      */                                                                                                  
3761     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3762         if (mPaused) {                                                                                   
3763             if (LOGD) Log.d(TAG, "Deferring update until onResume");                                     
3764             if (deletePreviousRunnables) {                                                               
3765                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3766                 }                                                                                        
3767             }                                                                                            
3768             mBindOnResumeCallbacks.add(run);                                                             
3769             return true;                                                                                 
3770         } else {                                                                                         
3771             return false;                                                                                
3772         }                                                                                                
3773     }                                                                                                    
3774                                                                                                          
3775     private boolean waitUntilResume(Runnable run) {                                                      
3776         return waitUntilResume(run, false);                                                              
3777     }                                                                                                    
3778                                                                                                          
3779     public void addOnResumeCallback(Runnable run) {                                                      
3780         mOnResumeCallbacks.add(run);                                                                     
3781     }                                                                                                    
3782                                                                                                          
3783     /**                                                                                                  
3784      * If the activity is currently paused, signal that we need to re-run the loader                     
3785      * in onResume.                                                                                      
3786      *                                                                                                   
3787      * This needs to be called from incoming places where resources might have been loaded               
3788      * while we are paused.  That is becaues the Configuration might be wrong                            
3789      * when we're not running, and if it comes back to what it was when we                               
3790      * were paused, we are not restarted.                                                                
3791      *                                                                                                   
3792      * Implementation of the method from LauncherModel.Callbacks.                                        
3793      *                                                                                                   
3794      * @return true if we are currently paused.  The caller might be able to                             
3795      * skip some work in that case since we will come back again.                                        
3796      */                                                                                                  
3797     public boolean setLoadOnResume() {                                                                   
3798         if (mPaused) {                                                                                   
3799             if (LOGD) Log.d(TAG, "setLoadOnResume");                                                     
3800             mOnResumeNeedsLoad = true;                                                                   
3801             return true;                                                                                 
3802         } else {                                                                                         
3803             return false;                                                                                
3804         }                                                                                                
3805     }                                                                                                    
3806                                                                                                          
3807     /**                                                                                                  
3808      * Implementation of the method from LauncherModel.Callbacks.                                        
3809      */                                                                                                  
3810     public int getCurrentWorkspaceScreen() {                                                             
3811         if (mWorkspace != null) {                                                                        
3812             return mWorkspace.getCurrentPage();                                                          
3813         } else {                                                                                         
3814             return SCREEN_COUNT / 2;                                                                     
3815         }                                                                                                
3816     }                                                                                                    
3817                                                                                                          
3818     /**                                                                                                  
3819      * Refreshes the shortcuts shown on the workspace.                                                   
3820      *                                                                                                   
3821      * Implementation of the method from LauncherModel.Callbacks.                                        
3822      */                                                                                                  
3823     public void startBinding() {                                                                         
3824         setWorkspaceLoading(true);                                                                       
3825                                                                                                          
3826         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3827         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3828         // from scratch again                                                                            
3829         mBindOnResumeCallbacks.clear();                                                                  
3830                                                                                                          
3831         // Clear the workspace because it's going to be rebound                                          
3832         mWorkspace.clearDropTargets();                                                                   
3833         mWorkspace.removeAllWorkspaceScreens();                                                          
3834                                                                                                          
3835         mWidgetsToAdvance.clear();                                                                       
3836         if (mHotseat != null) {                                                                          
3837             mHotseat.resetLayout();                                                                      
3838         }                                                                                                
3839     }                                                                                                    
3840                                                                                                          
3841     @Override                                                                                            
3842     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3843         bindAddScreens(orderedScreenIds);                                                                
3844                                                                                                          
3845         // If there are no screens, we need to have an empty screen                                      
3846         if (orderedScreenIds.size() == 0) {                                                              
3847             mWorkspace.addExtraEmptyScreen();                                                            
3848         }                                                                                                
3849                                                                                                          
3850         // Create the custom content page (this call updates mDefaultScreen which calls                  
3851         // setCurrentPage() so ensure that all pages are added before calling this).                     
3852         if (hasCustomContentToLeft()) {                                                                  
3853             mWorkspace.createCustomContentContainer();                                                   
3854             populateCustomContentContainer();                                                            
3855         }                                                                                                
3856     }                                                                                                    
3857                                                                                                          
3858     @Override                                                                                            
3859     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3860         // Log to disk                                                                                   
3861         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3862         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3863                 TextUtils.join(", ", orderedScreenIds), true);                                           
3864         int count = orderedScreenIds.size();                                                             
3865         for (int i = 0; i < count; i++) {                                                                
3866             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3867         }                                                                                                
3868     }                                                                                                    
3869                                                                                                          
3870     private boolean shouldShowWeightWatcher() {                                                          
3871         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3872         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3873         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3874                                                                                                          
3875         return show;                                                                                     
3876     }                                                                                                    
3877                                                                                                          
3878     private void toggleShowWeightWatcher() {                                                             
3879         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3880         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3881         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3882                                                                                                          
3883         show = !show;                                                                                    
3884                                                                                                          
3885         SharedPreferences.Editor editor = sp.edit();                                                     
3886         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3887         editor.commit();                                                                                 
3888                                                                                                          
3889         if (mWeightWatcher != null) {                                                                    
3890             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3891         }                                                                                                
3892     }                                                                                                    
3893                                                                                                          
3894     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3895                               final ArrayList<ItemInfo> addNotAnimated,                                  
3896                               final ArrayList<ItemInfo> addAnimated,                                     
3897                               final ArrayList<AppInfo> addedApps) {                                      
3898         Runnable r = new Runnable() {                                                                    
3899             public void run() {                                                                          
3900                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3901             }                                                                                            
3902         };                                                                                               
3903         if (waitUntilResume(r)) {                                                                        
3904             return;                                                                                      
3905         }                                                                                                
3906                                                                                                          
3907         // Add the new screens                                                                           
3908         if (newScreens != null) {                                                                        
3909             bindAddScreens(newScreens);                                                                  
3910         }                                                                                                
3911                                                                                                          
3912         // We add the items without animation on non-visible pages, and with                             
3913         // animations on the new page (which we will try and snap to).                                   
3914         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3915             bindItems(addNotAnimated, 0,                                                                 
3916                     addNotAnimated.size(), false);                                                       
3917         }                                                                                                
3918         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3919             bindItems(addAnimated, 0,                                                                    
3920                     addAnimated.size(), true);                                                           
3921         }                                                                                                
3922                                                                                                          
3923         // Remove the extra empty screen                                                                 
3924         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3925                                                                                                          
3926         if (addedApps != null && mAppsView != null) {                                                    
3927             mAppsView.addApps(addedApps);                                                                
3928         }                                                                                                
3929     }                                                                                                    
3930                                                                                                          
3931     /**                                                                                                  
3932      * Bind the items start-end from the list.                                                           
3933      *                                                                                                   
3934      * Implementation of the method from LauncherModel.Callbacks.                                        
3935      */                                                                                                  
3936     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3937                           final boolean forceAnimateIcons) {                                             
3938         Runnable r = new Runnable() {                                                                    
3939             public void run() {                                                                          
3940                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3941             }                                                                                            
3942         };                                                                                               
3943         if (waitUntilResume(r)) {                                                                        
3944             return;                                                                                      
3945         }                                                                                                
3946                                                                                                          
3947         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3948         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3949         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3950         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3951         Workspace workspace = mWorkspace;                                                                
3952         long newShortcutsScreenId = -1;                                                                  
3953         for (int i = start; i < end; i++) {                                                              
3954             final ItemInfo item = shortcuts.get(i);                                                      
3955                                                                                                          
3956             // Short circuit if we are loading dock items for a configuration which has no dock          
3957             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3958                     mHotseat == null) {                                                                  
3959                 continue;                                                                                
3960             }                                                                                            
3961                                                                                                          
3962             switch (item.itemType) {                                                                     
3963                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3964                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3965                     ShortcutInfo info = (ShortcutInfo) item;                                             
3966                     View shortcut = createShortcut(info);                                                
3967                                                                                                          
3968                     /*                                                                                   
3969                      * TODO: FIX collision case                                                          
3970                      */                                                                                  
3971                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3972                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3973                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3974                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3975                             Object tag = v.getTag();                                                     
3976                             String desc = "Collision while binding workspace item: " + item              
3977                                     + ". Collides with " + tag;                                          
3978                             if (LauncherAppState.isDogfoodBuild()) {                                     
3979                                 throw (new RuntimeException(desc));                                      
3980                             } else {                                                                     
3981                                 Log.d(TAG, desc);                                                        
3982                             }                                                                            
3983                         }                                                                                
3984                     }                                                                                    
3985                                                                                                          
3986                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3987                             item.cellY, 1, 1);                                                           
3988                     if (animateIcons) {                                                                  
3989                         // Animate all the applications up now                                           
3990                         shortcut.setAlpha(0f);                                                           
3991                         shortcut.setScaleX(0f);                                                          
3992                         shortcut.setScaleY(0f);                                                          
3993                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3994                         newShortcutsScreenId = item.screenId;                                            
3995                     }                                                                                    
3996                     break;                                                                               
3997                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3998                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3999                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4000                             (FolderInfo) item, mIconCache);                                              
4001                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4002                             item.cellY, 1, 1);                                                           
4003                     break;                                                                               
4004                 default:                                                                                 
4005                     throw new RuntimeException("Invalid Item Type");                                     
4006             }                                                                                            
4007         }                                                                                                
4008                                                                                                          
4009         if (animateIcons) {                                                                              
4010             // Animate to the correct page                                                               
4011             if (newShortcutsScreenId > -1) {                                                             
4012                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4013                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4014                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4015                     public void run() {                                                                  
4016                         anim.playTogether(bounceAnims);                                                  
4017                         anim.start();                                                                    
4018                     }                                                                                    
4019                 };                                                                                       
4020                 if (newShortcutsScreenId != currentScreenId) {                                           
4021                     // We post the animation slightly delayed to prevent slowdowns                       
4022                     // when we are loading right after we return to launcher.                            
4023                     mWorkspace.postDelayed(new Runnable() {                                              
4024                         public void run() {                                                              
4025                             if (mWorkspace != null) {                                                    
4026                                 mWorkspace.snapToPage(newScreenIndex);                                   
4027                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4028                                         NEW_APPS_ANIMATION_DELAY);                                       
4029                             }                                                                            
4030                         }                                                                                
4031                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4032                 } else {                                                                                 
4033                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4034                 }                                                                                        
4035             }                                                                                            
4036         }                                                                                                
4037         workspace.requestLayout();                                                                       
4038     }                                                                                                    
4039                                                                                                          
4040     /**                                                                                                  
4041      * Implementation of the method from LauncherModel.Callbacks.                                        
4042      */                                                                                                  
4043     public void bindFolders(final LongArrayMap<FolderInfo> folders) {                                    
4044         Runnable r = new Runnable() {                                                                    
4045             public void run() {                                                                          
4046                 bindFolders(folders);                                                                    
4047             }                                                                                            
4048         };                                                                                               
4049         if (waitUntilResume(r)) {                                                                        
4050             return;                                                                                      
4051         }                                                                                                
4052         sFolders = folders.clone();                                                                      
4053     }                                                                                                    
4054                                                                                                          
4055     /**                                                                                                  
4056      * Add the views for a widget to the workspace.                                                      
4057      *                                                                                                   
4058      * Implementation of the method from LauncherModel.Callbacks.                                        
4059      */                                                                                                  
4060     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4061         Runnable r = new Runnable() {                                                                    
4062             public void run() {                                                                          
4063                 bindAppWidget(item);                                                                     
4064             }                                                                                            
4065         };                                                                                               
4066         if (waitUntilResume(r)) {                                                                        
4067             return;                                                                                      
4068         }                                                                                                
4069                                                                                                          
4070         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4071         if (DEBUG_WIDGETS) {                                                                             
4072             Log.d(TAG, "bindAppWidget: " + item);                                                        
4073         }                                                                                                
4074         final Workspace workspace = mWorkspace;                                                          
4075                                                                                                          
4076         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
4077                 LauncherModel.getProviderInfo(this, item.providerName, item.user);                       
4078                                                                                                          
4079         if (!mIsSafeModeEnabled                                                                          
4080                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
4081                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
4082             if (appWidgetInfo == null) {                                                                 
4083                 if (DEBUG_WIDGETS) {                                                                     
4084                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4085                             + " belongs to component " + item.providerName                               
4086                             + ", as the povider is null");                                               
4087                 }                                                                                        
4088                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4089                 return;                                                                                  
4090             }                                                                                            
4091             // Note: This assumes that the id remap broadcast is received before this step.              
4092             // If that is not the case, the id remap will be ignored and user may see the                
4093             // click to setup view.                                                                      
4094             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);      
4095             pendingInfo.spanX = item.spanX;                                                              
4096             pendingInfo.spanY = item.spanY;                                                              
4097             pendingInfo.minSpanX = item.minSpanX;                                                        
4098             pendingInfo.minSpanY = item.minSpanY;                                                        
4099             Bundle options = null;                                                                       
4100                     WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);                  
4101                                                                                                          
4102             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4103             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4104                     newWidgetId, appWidgetInfo, options);                                                
4105                                                                                                          
4106             // TODO consider showing a permission dialog when the widget is clicked.                     
4107             if (!success) {                                                                              
4108                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4109                 if (DEBUG_WIDGETS) {                                                                     
4110                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4111                             + " belongs to component " + item.providerName                               
4112                             + ", as the launcher is unable to bing a new widget id");                    
4113                 }                                                                                        
4114                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4115                 return;                                                                                  
4116             }                                                                                            
4117                                                                                                          
4118             item.appWidgetId = newWidgetId;                                                              
4119                                                                                                          
4120             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4121             // the widget is ready to go.                                                                
4122             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4123                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4124                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4125                                                                                                          
4126             LauncherModel.updateItemInDatabase(this, item);                                              
4127         }                                                                                                
4128                                                                                                          
4129         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
4130             final int appWidgetId = item.appWidgetId;                                                    
4131             if (DEBUG_WIDGETS) {                                                                         
4132                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
4133                         + appWidgetInfo.provider);                                                       
4134             }                                                                                            
4135                                                                                                          
4136             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4137         } else {                                                                                         
4138             appWidgetInfo = null;                                                                        
4139             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
4140                     mIsSafeModeEnabled);                                                                 
4141             view.updateIcon(mIconCache);                                                                 
4142             item.hostView = view;                                                                        
4143             item.hostView.updateAppWidget(null);                                                         
4144             item.hostView.setOnClickListener(this);                                                      
4145         }                                                                                                
4146                                                                                                          
4147         item.hostView.setTag(item);                                                                      
4148         item.onBindAppWidget(this);                                                                      
4149                                                                                                          
4150         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4151                 item.cellY, item.spanX, item.spanY, false);                                              
4152         if (!item.isCustomWidget()) {                                                                    
4153             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
4154         }                                                                                                
4155                                                                                                          
4156         workspace.requestLayout();                                                                       
4157                                                                                                          
4158         if (DEBUG_WIDGETS) {                                                                             
4159             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4160                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4161         }                                                                                                
4162     }                                                                                                    
4163                                                                                                          
4164     /**                                                                                                  
4165      * Restores a pending widget.                                                                        
4166      *                                                                                                   
4167      * @param appWidgetId The app widget id                                                              
4168      * @param cellInfo The position on screen where to create the widget.                                
4169      */                                                                                                  
4170     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4171         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4172         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4173             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4174             return;                                                                                      
4175         }                                                                                                
4176                                                                                                          
4177         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4178         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4179                                                                                                          
4180         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4181         LauncherModel.updateItemInDatabase(this, info);                                                  
4182     }                                                                                                    
4183                                                                                                          
4184     public void onPageBoundSynchronously(int page) {                                                     
4185         mSynchronouslyBoundPages.add(page);                                                              
4186     }                                                                                                    
4187                                                                                                          
4188     /**                                                                                                  
4189      * Callback saying that there aren't any more items to bind.                                         
4190      *                                                                                                   
4191      * Implementation of the method from LauncherModel.Callbacks.                                        
4192      */                                                                                                  
4193     public void finishBindingItems() {                                                                   
4194         Runnable r = new Runnable() {                                                                    
4195             public void run() {                                                                          
4196                 finishBindingItems();                                                                    
4197             }                                                                                            
4198         };                                                                                               
4199         if (waitUntilResume(r)) {                                                                        
4200             return;                                                                                      
4201         }                                                                                                
4202         if (mSavedState != null) {                                                                       
4203             if (!mWorkspace.hasFocus()) {                                                                
4204                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4205             }                                                                                            
4206             mSavedState = null;                                                                          
4207         }                                                                                                
4208                                                                                                          
4209         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4210                                                                                                          
4211         setWorkspaceLoading(false);                                                                      
4212         sendLoadingCompleteBroadcastIfNecessary();                                                       
4213                                                                                                          
4214         // If we received the result of any pending adds while the loader was running (e.g. the          
4215         // widget configuration forced an orientation change), process them now.                         
4216         if (sPendingAddItem != null) {                                                                   
4217             final long screenId = completeAdd(sPendingAddItem);                                          
4218                                                                                                          
4219             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4220             // the screen would be guaranteed to exist after bind, and the page would be set through     
4221             // the workspace restore process.                                                            
4222             mWorkspace.post(new Runnable() {                                                             
4223                 @Override                                                                                
4224                 public void run() {                                                                      
4225                     mWorkspace.snapToScreenId(screenId);                                                 
4226                 }                                                                                        
4227             });                                                                                          
4228             sPendingAddItem = null;                                                                      
4229         }                                                                                                
4230                                                                                                          
4231         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
4232                                                                                                          
4233         if (mLauncherCallbacks != null) {                                                                
4234             mLauncherCallbacks.finishBindingItems(false);                                                
4235         }                                                                                                
4236     }                                                                                                    
4237                                                                                                          
4238     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4239         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4240             String permission =                                                                          
4241                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4242             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4243             sendBroadcast(intent, permission);                                                           
4244             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4245             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4246             editor.apply();                                                                              
4247         }                                                                                                
4248     }                                                                                                    
4249                                                                                                          
4250     public boolean isAllAppsButtonRank(int rank) {                                                       
4251         if (mHotseat != null) {                                                                          
4252             return mHotseat.isAllAppsButtonRank(rank);                                                   
4253         }                                                                                                
4254         return false;                                                                                    
4255     }                                                                                                    
4256                                                                                                          
4257     private boolean canRunNewAppsAnimation() {                                                           
4258         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4259         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4260     }                                                                                                    
4261                                                                                                          
4262     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4263         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4264                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4265                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4266                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4267         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4268         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4269         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4270         return bounceAnim;                                                                               
4271     }                                                                                                    
4272                                                                                                          
4273     public boolean useVerticalBarLayout() {                                                              
4274         return mDeviceProfile.isVerticalBarLayout();                                                     
4275     }                                                                                                    
4276                                                                                                          
4277     protected Rect getSearchBarBounds() {                                                                
4278         return mDeviceProfile.getSearchBarBounds(Utilities.isRtl(getResources()));                       
4279     }                                                                                                    
4280                                                                                                          
4281     public void bindSearchablesChanged() {                                                               
4282         if (mSearchDropTargetBar == null) {                                                              
4283             return;                                                                                      
4284         }                                                                                                
4285         if (mQsb != null) {                                                                              
4286             mSearchDropTargetBar.removeView(mQsb);                                                       
4287             mQsb = null;                                                                                 
4288         }                                                                                                
4289         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4290     }                                                                                                    
4291                                                                                                          
4292     /**                                                                                                  
4293      * A runnable that we can dequeue and re-enqueue when all applications are bound (to prevent         
4294      * multiple calls to bind the same list.)                                                            
4295      */                                                                                                  
4296     @Thunk ArrayList<AppInfo> mTmpAppsList;                                                              
4297     private Runnable mBindAllApplicationsRunnable = new Runnable() {                                     
4298         public void run() {                                                                              
4299             bindAllApplications(mTmpAppsList);                                                           
4300             mTmpAppsList = null;                                                                         
4301         }                                                                                                
4302     };                                                                                                   
4303                                                                                                          
4304     /**                                                                                                  
4305      * Add the icons for all apps.                                                                       
4306      *                                                                                                   
4307      * Implementation of the method from LauncherModel.Callbacks.                                        
4308      */                                                                                                  
4309     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4310         if (waitUntilResume(mBindAllApplicationsRunnable, true)) {                                       
4311             mTmpAppsList = apps;                                                                         
4312             return;                                                                                      
4313         }                                                                                                
4314                                                                                                          
4315         if (mAppsView != null) {                                                                         
4316             mAppsView.setApps(apps);                                                                     
4317         }                                                                                                
4318         if (mLauncherCallbacks != null) {                                                                
4319             mLauncherCallbacks.bindAllApplications(apps);                                                
4320         }                                                                                                
4321     }                                                                                                    
4322                                                                                                          
4323     /**                                                                                                  
4324      * A package was updated.                                                                            
4325      *                                                                                                   
4326      * Implementation of the method from LauncherModel.Callbacks.                                        
4327      */                                                                                                  
4328     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4329         Runnable r = new Runnable() {                                                                    
4330             public void run() {                                                                          
4331                 bindAppsUpdated(apps);                                                                   
4332             }                                                                                            
4333         };                                                                                               
4334         if (waitUntilResume(r)) {                                                                        
4335             return;                                                                                      
4336         }                                                                                                
4337                                                                                                          
4338         if (mAppsView != null) {                                                                         
4339             mAppsView.updateApps(apps);                                                                  
4340         }                                                                                                
4341     }                                                                                                    
4342                                                                                                          
4343     @Override                                                                                            
4344     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4345         Runnable r = new Runnable() {                                                                    
4346             public void run() {                                                                          
4347                 bindWidgetsRestored(widgets);                                                            
4348             }                                                                                            
4349         };                                                                                               
4350         if (waitUntilResume(r)) {                                                                        
4351             return;                                                                                      
4352         }                                                                                                
4353         mWorkspace.widgetsRestored(widgets);                                                             
4354     }                                                                                                    
4355                                                                                                          
4356     /**                                                                                                  
4357      * Some shortcuts were updated in the background.                                                    
4358      *                                                                                                   
4359      * Implementation of the method from LauncherModel.Callbacks.                                        
4360      */                                                                                                  
4361     @Override                                                                                            
4362     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4363             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4364         Runnable r = new Runnable() {                                                                    
4365             public void run() {                                                                          
4366                 bindShortcutsChanged(updated, removed, user);                                            
4367             }                                                                                            
4368         };                                                                                               
4369         if (waitUntilResume(r)) {                                                                        
4370             return;                                                                                      
4371         }                                                                                                
4372                                                                                                          
4373         if (!updated.isEmpty()) {                                                                        
4374             mWorkspace.updateShortcuts(updated);                                                         
4375         }                                                                                                
4376                                                                                                          
4377         if (!removed.isEmpty()) {                                                                        
4378             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4379             for (ShortcutInfo si : removed) {                                                            
4380                 removedComponents.add(si.getTargetComponent());                                          
4381             }                                                                                            
4382             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4383             // Notify the drag controller                                                                
4384             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4385         }                                                                                                
4386     }                                                                                                    
4387                                                                                                          
4388     /**                                                                                                  
4389      * Update the state of a package, typically related to install state.                                
4390      *                                                                                                   
4391      * Implementation of the method from LauncherModel.Callbacks.                                        
4392      */                                                                                                  
4393     @Override                                                                                            
4394     public void bindRestoreItemsChange(final HashSet<ItemInfo> updates) {                                
4395         Runnable r = new Runnable() {                                                                    
4396             public void run() {                                                                          
4397                 bindRestoreItemsChange(updates);                                                         
4398             }                                                                                            
4399         };                                                                                               
4400         if (waitUntilResume(r)) {                                                                        
4401             return;                                                                                      
4402         }                                                                                                
4403                                                                                                          
4404         mWorkspace.updateRestoreItems(updates);                                                          
4405     }                                                                                                    
4406                                                                                                          
4407     /**                                                                                                  
4408      * A package was uninstalled.  We take both the super set of packageNames                            
4409      * in addition to specific applications to remove, the reason being that                             
4410      * this can be called when a package is updated as well.  In that scenario,                          
4411      * we only remove specific components from the workspace, where as                                   
4412      * package-removal should clear all items by package name.                                           
4413      *                                                                                                   
4414      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4415      * Implementation of the method from LauncherModel.Callbacks.                                        
4416      */                                                                                                  
4417     @Override                                                                                            
4418     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4419             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4420         Runnable r = new Runnable() {                                                                    
4421             public void run() {                                                                          
4422                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4423             }                                                                                            
4424         };                                                                                               
4425         if (waitUntilResume(r)) {                                                                        
4426             return;                                                                                      
4427         }                                                                                                
4428                                                                                                          
4429         if (reason == 0) {                                                                               
4430             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4431             for (AppInfo info : appInfos) {                                                              
4432                 removedComponents.add(info.componentName);                                               
4433             }                                                                                            
4434             if (!packageNames.isEmpty()) {                                                               
4435                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4436             }                                                                                            
4437             if (!removedComponents.isEmpty()) {                                                          
4438                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4439             }                                                                                            
4440             // Notify the drag controller                                                                
4441             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4442                                                                                                          
4443         } else {                                                                                         
4444             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4445         }                                                                                                
4446                                                                                                          
4447         // Update AllApps                                                                                
4448         if (mAppsView != null) {                                                                         
4449             mAppsView.removeApps(appInfos);                                                              
4450         }                                                                                                
4451     }                                                                                                    
4452                                                                                                          
4453     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4454             public void run() {                                                                          
4455                 bindAllPackages(mWidgetsModel);                                                          
4456             }                                                                                            
4457         };                                                                                               
4458                                                                                                          
4459     @Override                                                                                            
4460     public void bindAllPackages(final WidgetsModel model) {                                              
4461         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4462             mWidgetsModel = model;                                                                       
4463             return;                                                                                      
4464         }                                                                                                
4465                                                                                                          
4466         if (mWidgetsView != null && model != null) {                                                     
4467             mWidgetsView.addWidgets(model);                                                              
4468             mWidgetsModel = null;                                                                        
4469         }                                                                                                
4470     }                                                                                                    
4471                                                                                                          
4472     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4473         final Display d = getWindowManager().getDefaultDisplay();                                        
4474         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4475         switch (d.getRotation()) {                                                                       
4476         case Surface.ROTATION_0:                                                                         
4477         case Surface.ROTATION_180:                                                                       
4478             // We are currently in the same basic orientation as the natural orientation                 
4479             naturalOri = configOri;                                                                      
4480             break;                                                                                       
4481         case Surface.ROTATION_90:                                                                        
4482         case Surface.ROTATION_270:                                                                       
4483             // We are currently in the other basic orientation to the natural orientation                
4484             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4485                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4486             break;                                                                                       
4487         }                                                                                                
4488                                                                                                          
4489         int[] oriMap = {                                                                                 
4490                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4491                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4492                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4493                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4494         };                                                                                               
4495         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4496         // is landscape.                                                                                 
4497         int indexOffset = 0;                                                                             
4498         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4499             indexOffset = 1;                                                                             
4500         }                                                                                                
4501         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4502     }                                                                                                    
4503                                                                                                          
4504     public void lockScreenOrientation() {                                                                
4505         if (Utilities.isRotationEnabled(this)) {                                                         
4506             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4507                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4508                         .getConfiguration().orientation));                                               
4509             } else {                                                                                     
4510                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4511             }                                                                                            
4512         }                                                                                                
4513     }                                                                                                    
4514     public void unlockScreenOrientation(boolean immediate) {                                             
4515         if (Utilities.isRotationEnabled(this)) {                                                         
4516             if (immediate) {                                                                             
4517                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4518             } else {                                                                                     
4519                 mHandler.postDelayed(new Runnable() {                                                    
4520                     public void run() {                                                                  
4521                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4522                     }                                                                                    
4523                 }, mRestoreScreenOrientationDelay);                                                      
4524             }                                                                                            
4525         }                                                                                                
4526     }                                                                                                    
4527                                                                                                          
4528     protected boolean isLauncherPreinstalled() {                                                         
4529         if (mLauncherCallbacks != null) {                                                                
4530             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4531         }                                                                                                
4532         PackageManager pm = getPackageManager();                                                         
4533         try {                                                                                            
4534             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4535             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4536                 return true;                                                                             
4537             } else {                                                                                     
4538                 return false;                                                                            
4539             }                                                                                            
4540         } catch (NameNotFoundException e) {                                                              
4541             e.printStackTrace();                                                                         
4542             return false;                                                                                
4543         }                                                                                                
4544     }                                                                                                    
4545                                                                                                          
4546     /**                                                                                                  
4547      * This method indicates whether or not we should suggest default wallpaper dimensions               
4548      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4549      */                                                                                                  
4550     protected boolean overrideWallpaperDimensions() {                                                    
4551         if (mLauncherCallbacks != null) {                                                                
4552             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4553         }                                                                                                
4554         return true;                                                                                     
4555     }                                                                                                    
4556                                                                                                          
4557     /**                                                                                                  
4558      * To be overridden by subclasses to indicate that there is an activity to launch                    
4559      * before showing the standard launcher experience.                                                  
4560      */                                                                                                  
4561     protected boolean hasFirstRunActivity() {                                                            
4562         if (mLauncherCallbacks != null) {                                                                
4563             return mLauncherCallbacks.hasFirstRunActivity();                                             
4564         }                                                                                                
4565         return false;                                                                                    
4566     }                                                                                                    
4567                                                                                                          
4568     /**                                                                                                  
4569      * To be overridden by subclasses to launch any first run activity                                   
4570      */                                                                                                  
4571     protected Intent getFirstRunActivity() {                                                             
4572         if (mLauncherCallbacks != null) {                                                                
4573             return mLauncherCallbacks.getFirstRunActivity();                                             
4574         }                                                                                                
4575         return null;                                                                                     
4576     }                                                                                                    
4577                                                                                                          
4578     /**                                                                                                  
4579      * Returns whether the launcher callbacks overrides search in all apps.                              
4580      */                                                                                                  
4581     @Thunk boolean isAllAppsSearchOverridden() {                                                         
4582         if (DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                       
4583             return false;                                                                                
4584         }                                                                                                
4585                                                                                                          
4586         if (mLauncherCallbacks != null) {                                                                
4587             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4588         }                                                                                                
4589         return false;                                                                                    
4590     }                                                                                                    
4591                                                                                                          
4592     private boolean shouldRunFirstRunActivity() {                                                        
4593         return !ActivityManager.isRunningInTestHarness() &&                                              
4594                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4595     }                                                                                                    
4596                                                                                                          
4597     protected boolean hasRunFirstRunActivity() {                                                         
4598         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4599     }                                                                                                    
4600                                                                                                          
4601     public boolean showFirstRunActivity() {                                                              
4602         if (shouldRunFirstRunActivity() &&                                                               
4603                 hasFirstRunActivity()) {                                                                 
4604             Intent firstRunIntent = getFirstRunActivity();                                               
4605             if (firstRunIntent != null) {                                                                
4606                 startActivity(firstRunIntent);                                                           
4607                 markFirstRunActivityShown();                                                             
4608                 return true;                                                                             
4609             }                                                                                            
4610         }                                                                                                
4611         return false;                                                                                    
4612     }                                                                                                    
4613                                                                                                          
4614     private void markFirstRunActivityShown() {                                                           
4615         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4616         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4617         editor.apply();                                                                                  
4618     }                                                                                                    
4619                                                                                                          
4620     /**                                                                                                  
4621      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4622      * screen that must be displayed and dismissed.                                                      
4623      */                                                                                                  
4624     protected boolean hasDismissableIntroScreen() {                                                      
4625         if (mLauncherCallbacks != null) {                                                                
4626             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4627         }                                                                                                
4628         return false;                                                                                    
4629     }                                                                                                    
4630                                                                                                          
4631     /**                                                                                                  
4632      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4633      */                                                                                                  
4634     protected View getIntroScreen() {                                                                    
4635         if (mLauncherCallbacks != null) {                                                                
4636             return mLauncherCallbacks.getIntroScreen();                                                  
4637         }                                                                                                
4638         return null;                                                                                     
4639     }                                                                                                    
4640                                                                                                          
4641     /**                                                                                                  
4642      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4643      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4644      */                                                                                                  
4645     private boolean shouldShowIntroScreen() {                                                            
4646         return hasDismissableIntroScreen() &&                                                            
4647                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4648     }                                                                                                    
4649                                                                                                          
4650     protected void showIntroScreen() {                                                                   
4651         View introScreen = getIntroScreen();                                                             
4652         changeWallpaperVisiblity(false);                                                                 
4653         if (introScreen != null) {                                                                       
4654             mDragLayer.showOverlayView(introScreen);                                                     
4655         }                                                                                                
4656         if (mLauncherOverlayContainer != null) {                                                         
4657             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4658         }                                                                                                
4659     }                                                                                                    
4660                                                                                                          
4661     public void dismissIntroScreen() {                                                                   
4662         markIntroScreenDismissed();                                                                      
4663         if (showFirstRunActivity()) {                                                                    
4664             // We delay hiding the intro view until the first run activity is showing. This              
4665             // avoids a blip.                                                                            
4666             mWorkspace.postDelayed(new Runnable() {                                                      
4667                 @Override                                                                                
4668                 public void run() {                                                                      
4669                     mDragLayer.dismissOverlayView();                                                     
4670                     if (mLauncherOverlayContainer != null) {                                             
4671                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4672                     }                                                                                    
4673                     showFirstRunClings();                                                                
4674                 }                                                                                        
4675             }, ACTIVITY_START_DELAY);                                                                    
4676         } else {                                                                                         
4677             mDragLayer.dismissOverlayView();                                                             
4678             if (mLauncherOverlayContainer != null) {                                                     
4679                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4680             }                                                                                            
4681             showFirstRunClings();                                                                        
4682         }                                                                                                
4683         changeWallpaperVisiblity(true);                                                                  
4684     }                                                                                                    
4685                                                                                                          
4686     private void markIntroScreenDismissed() {                                                            
4687         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4688         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4689         editor.apply();                                                                                  
4690     }                                                                                                    
4691                                                                                                          
4692     @Thunk void showFirstRunClings() {                                                                   
4693         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4694         // on the device, then we always show the first run cling experience (or if there is no          
4695         // launcher2). Otherwise, we prompt the user upon started for migration                          
4696         LauncherClings launcherClings = new LauncherClings(this);                                        
4697         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4698             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4699                 launcherClings.showMigrationCling();                                                     
4700             } else {                                                                                     
4701                 launcherClings.showLongPressCling(true);                                                 
4702             }                                                                                            
4703         }                                                                                                
4704     }                                                                                                    
4705                                                                                                          
4706     void showWorkspaceSearchAndHotseat() {                                                               
4707         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4708         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4709         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4710         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4711     }                                                                                                    
4712                                                                                                          
4713     void hideWorkspaceSearchAndHotseat() {                                                               
4714         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4715         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4716         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4717         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4718     }                                                                                                    
4719                                                                                                          
4720     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4721         // Called from search suggestion, not supported in other profiles.                               
4722         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4723         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4724         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
4725                 myUser);                                                                                 
4726         if (activityInfo == null) {                                                                      
4727             return null;                                                                                 
4728         }                                                                                                
4729         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4730     }                                                                                                    
4731                                                                                                          
4732     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4733             Bitmap icon) {                                                                               
4734         // Called from search suggestion, not supported in other profiles.                               
4735         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4736                 UserHandleCompat.myUserHandle());                                                        
4737     }                                                                                                    
4738                                                                                                          
4739     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4740             Bitmap icon, UserHandleCompat user) {                                                        
4741         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4742         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4743         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4744     }                                                                                                    
4745                                                                                                          
4746     protected void moveWorkspaceToDefaultScreen() {                                                      
4747         mWorkspace.moveToDefaultScreen(false);                                                           
4748     }                                                                                                    
4749                                                                                                          
4750     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4751         dragView.setTag(dragInfo);                                                                       
4752         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4753         mWorkspace.beginExternalDragShared(dragView, source);                                            
4754     }                                                                                                    
4755                                                                                                          
4756     @Override                                                                                            
4757     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4758         if (mLauncherCallbacks != null) {                                                                
4759             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4760         }                                                                                                
4761     }                                                                                                    
4762                                                                                                          
4763     /**                                                                                                  
4764      * Prints out out state for debugging.                                                               
4765      */                                                                                                  
4766     public void dumpState() {                                                                            
4767         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4768         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4769         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4770         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4771         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4772         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4773         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4774         mModel.dumpState();                                                                              
4775         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4776                                                                                                          
4777         Log.d(TAG, "END launcher3 dump state");                                                          
4778     }                                                                                                    
4779                                                                                                          
4780     @Override                                                                                            
4781     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4782         super.dump(prefix, fd, writer, args);                                                            
4783         synchronized (sDumpLogs) {                                                                       
4784             writer.println(" ");                                                                         
4785             writer.println("Debug logs: ");                                                              
4786             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4787                 writer.println("  " + sDumpLogs.get(i));                                                 
4788             }                                                                                            
4789         }                                                                                                
4790         if (mLauncherCallbacks != null) {                                                                
4791             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4792         }                                                                                                
4793     }                                                                                                    
4794                                                                                                          
4795     public static void dumpDebugLogsToConsole() {                                                        
4796         if (DEBUG_DUMP_LOG) {                                                                            
4797             synchronized (sDumpLogs) {                                                                   
4798                 Log.d(TAG, "");                                                                          
4799                 Log.d(TAG, "*********************");                                                     
4800                 Log.d(TAG, "Launcher debug logs: ");                                                     
4801                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4802                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4803                 }                                                                                        
4804                 Log.d(TAG, "*********************");                                                     
4805                 Log.d(TAG, "");                                                                          
4806             }                                                                                            
4807         }                                                                                                
4808     }                                                                                                    
4809                                                                                                          
4810     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4811         addDumpLog(tag, log, null, debugLog);                                                            
4812     }                                                                                                    
4813                                                                                                          
4814     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4815         if (debugLog) {                                                                                  
4816             if (e != null) {                                                                             
4817                 Log.d(tag, log, e);                                                                      
4818             } else {                                                                                     
4819                 Log.d(tag, log);                                                                         
4820             }                                                                                            
4821         }                                                                                                
4822         if (DEBUG_DUMP_LOG) {                                                                            
4823             sDateStamp.setTime(System.currentTimeMillis());                                              
4824             synchronized (sDumpLogs) {                                                                   
4825                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4826                     + (e == null ? "" : (", Exception: " + e)));                                         
4827             }                                                                                            
4828         }                                                                                                
4829     }                                                                                                    
4830                                                                                                          
4831     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4832         return sCustomAppWidgets.get(name);                                                              
4833     }                                                                                                    
4834                                                                                                          
4835     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4836         return sCustomAppWidgets;                                                                        
4837     }                                                                                                    
4838                                                                                                          
4839     public void dumpLogsToLocalData() {                                                                  
4840         if (DEBUG_DUMP_LOG) {                                                                            
4841             new AsyncTask<Void, Void, Void>() {                                                          
4842                 public Void doInBackground(Void ... args) {                                              
4843                     boolean success = false;                                                             
4844                     sDateStamp.setTime(sRunStart);                                                       
4845                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4846                             + sDateStamp.getDay() + "_"                                                  
4847                             + sDateStamp.getHours() + "-"                                                
4848                             + sDateStamp.getMinutes() + "_"                                              
4849                             + sDateStamp.getSeconds() + ".txt";                                          
4850                                                                                                          
4851                     FileOutputStream fos = null;                                                         
4852                     File outFile = null;                                                                 
4853                     try {                                                                                
4854                         outFile = new File(getFilesDir(), FILENAME);                                     
4855                         outFile.createNewFile();                                                         
4856                         fos = new FileOutputStream(outFile);                                             
4857                     } catch (Exception e) {                                                              
4858                         e.printStackTrace();                                                             
4859                     }                                                                                    
4860                     if (fos != null) {                                                                   
4861                         PrintWriter writer = new PrintWriter(fos);                                       
4862                                                                                                          
4863                         writer.println(" ");                                                             
4864                         writer.println("Debug logs: ");                                                  
4865                         synchronized (sDumpLogs) {                                                       
4866                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4867                                 writer.println("  " + sDumpLogs.get(i));                                 
4868                             }                                                                            
4869                         }                                                                                
4870                         writer.close();                                                                  
4871                     }                                                                                    
4872                     try {                                                                                
4873                         if (fos != null) {                                                               
4874                             fos.close();                                                                 
4875                             success = true;                                                              
4876                         }                                                                                
4877                     } catch (IOException e) {                                                            
4878                         e.printStackTrace();                                                             
4879                     }                                                                                    
4880                     return null;                                                                         
4881                 }                                                                                        
4882             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4883         }                                                                                                
4884     }                                                                                                    
4885 }                                                                                                        
4886                                                                                                          
4887 interface DebugIntents {                                                                                 
4888     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
4889     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
4890 }                                                                                                        
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.SuppressLint;                                                                  
  26 import android.annotation.TargetApi;                                                                     
  27 import android.app.Activity;                                                                             
  28 import android.app.ActivityManager;                                                                      
  29 import android.app.ActivityOptions;                                                                      
  30 import android.app.AlertDialog;                                                                          
  31 import android.app.SearchManager;                                                                        
  32 import android.appwidget.AppWidgetHostView;                                                              
  33 import android.appwidget.AppWidgetManager;                                                               
  34 import android.appwidget.AppWidgetProviderInfo;                                                          
  35 import android.content.ActivityNotFoundException;                                                        
  36 import android.content.BroadcastReceiver;                                                                
  37 import android.content.ComponentCallbacks2;                                                              
  38 import android.content.ComponentName;                                                                    
  39 import android.content.ContentResolver;                                                                  
  40 import android.content.Context;                                                                          
  41 import android.content.DialogInterface;                                                                  
  42 import android.content.Intent;                                                                           
  43 import android.content.IntentFilter;                                                                     
  44 import android.content.IntentSender;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.database.ContentObserver;                                                                 
  52 import android.database.sqlite.SQLiteDatabase;                                                           
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.PorterDuff;                                                                      
  57 import android.graphics.Rect;                                                                            
  58 import android.graphics.drawable.ColorDrawable;                                                          
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.text.Selection;                                                                           
  70 import android.text.SpannableStringBuilder;                                                              
  71 import android.text.TextUtils;                                                                           
  72 import android.text.method.TextKeyListener;                                                              
  73 import android.util.Log;                                                                                 
  74 import android.view.Display;                                                                             
  75 import android.view.Gravity;                                                                             
  76 import android.view.HapticFeedbackConstants;                                                             
  77 import android.view.KeyEvent;                                                                            
  78 import android.view.LayoutInflater;                                                                      
  79 import android.view.Menu;                                                                                
  80 import android.view.MotionEvent;                                                                         
  81 import android.view.Surface;                                                                             
  82 import android.view.View;                                                                                
  83 import android.view.View.OnClickListener;                                                                
  84 import android.view.View.OnLongClickListener;                                                            
  85 import android.view.ViewGroup;                                                                           
  86 import android.view.ViewStub;                                                                            
  87 import android.view.ViewTreeObserver;                                                                    
  88 import android.view.Window;                                                                              
  89 import android.view.WindowManager;                                                                       
  90 import android.view.accessibility.AccessibilityEvent;                                                    
  91 import android.view.inputmethod.InputMethodManager;                                                      
  92 import android.widget.Advanceable;                                                                       
  93 import android.widget.FrameLayout;                                                                       
  94 import android.widget.ImageView;                                                                         
  95 import android.widget.TextView;                                                                          
  96 import android.widget.Toast;                                                                             
  97                                                                                                          
  98 import com.android.launcher3.DropTarget.DragObject;                                                      
  99 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 100 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;                                
 101 import com.android.launcher3.allapps.AllAppsContainerView;                                               
 102 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 103 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 104 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 105 import com.android.launcher3.compat.UserHandleCompat;                                                    
 106 import com.android.launcher3.compat.UserManagerCompat;                                                   
 107 import com.android.launcher3.model.WidgetsModel;                                                         
 108 import com.android.launcher3.util.LongArrayMap;                                                          
 109 import com.android.launcher3.util.Thunk;                                                                 
 110 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 111 import com.android.launcher3.widget.WidgetHostViewLoader;                                                
 112 import com.android.launcher3.widget.WidgetsContainerView;                                                
 113                                                                                                          
 114 import java.io.DataInputStream;                                                                          
 115 import java.io.DataOutputStream;                                                                         
 116 import java.io.File;                                                                                     
 117 import java.io.FileDescriptor;                                                                           
 118 import java.io.FileNotFoundException;                                                                    
 119 import java.io.FileOutputStream;                                                                         
 120 import java.io.IOException;                                                                              
 121 import java.io.PrintWriter;                                                                              
 122 import java.lang.reflect.InvocationTargetException;                                                      
 123 import java.lang.reflect.Method;                                                                         
 124 import java.text.DateFormat;                                                                             
 125 import java.util.ArrayList;                                                                              
 126 import java.util.Collection;                                                                             
 127 import java.util.Date;                                                                                   
 128 import java.util.HashMap;                                                                                
 129 import java.util.HashSet;                                                                                
 130 import java.util.List;                                                                                   
 131 import java.util.concurrent.atomic.AtomicInteger;                                                        
 132                                                                                                          
 133 /**                                                                                                      
 134  * Default launcher application.                                                                         
 135  */                                                                                                      
 136 public class Launcher extends Activity                                                                   
 137         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 138                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 139                    LauncherStateTransitionAnimation.Callbacks {                                          
 140     static final String TAG = "Launcher";                                                                
 141     static final boolean LOGD = false;                                                                   
 142                                                                                                          
 143     // Temporary flag                                                                                    
 144     static final boolean DISABLE_ALL_APPS_SEARCH_INTEGRATION = true;                                     
 145                                                                                                          
 146     static final boolean PROFILE_STARTUP = false;                                                        
 147     static final boolean DEBUG_WIDGETS = true;                                                           
 148     static final boolean DEBUG_STRICT_MODE = false;                                                      
 149     static final boolean DEBUG_RESUME_TIME = false;                                                      
 150     static final boolean DEBUG_DUMP_LOG = false;                                                         
 151                                                                                                          
 152     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 153                                                                                                          
 154     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 155     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 156     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 157     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 158                                                                                                          
 159     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 160     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 161                                                                                                          
 162     private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;                                          
 163     private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;                                       
 164     private static final int WORKSPACE_BACKGROUND_BLACK = 2;                                             
 165                                                                                                          
 166     /**                                                                                                  
 167      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 168      * request codes used internally.                                                                    
 169      */                                                                                                  
 170     protected static final int REQUEST_LAST = 100;                                                       
 171                                                                                                          
 172     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 173                                                                                                          
 174     static final int SCREEN_COUNT = 5;                                                                   
 175                                                                                                          
 176     // To turn on these properties, type                                                                 
 177     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 178     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 179                                                                                                          
 180     // The Intent extra that defines whether to ignore the launch animation                              
 181     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 182             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 183                                                                                                          
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE = "launcher.state";                                        
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 192     // Type: int                                                                                         
 193     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 194     // Type: int                                                                                         
 195     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 196     // Type: int                                                                                         
 197     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 198     // Type: int                                                                                         
 199     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 200     // Type: parcelable                                                                                  
 201     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 202     // Type: parcelable                                                                                  
 203     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 204     // Type: int[]                                                                                       
 205     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 206                                                                                                          
 207     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 208     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 209                                                                                                          
 210     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 211     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 212             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 213                                                                                                          
 214     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 215     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 216                                                                                                          
 217     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 218     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 219                                                                                                          
 220     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 221                                                                                                          
 222     /** The different states that Launcher can be in. */                                                 
 223                                                                                                          
 224                                                                                                          
 225     /** The different states that Launcher can be in. */                                                 
 226     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED,, };;         
 227     @Thunk State mState = State.WORKSPACE;                                                               
 228     @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                   
 229                                                                                                          
 230     private boolean mIsSafeModeEnabled;                                                                  
 231                                                                                                          
 232     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 233     LauncherOverlay mLauncherOverlay;                                                                    
 234     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 235                                                                                                          
 236     static final int APPWIDGET_HOST_ID = 1024;                                                           
 237     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 238     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 239     private static final int ACTIVITY_START_DELAY = 1000;                                                
 240                                                                                                          
 241     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 242     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 243                                                                                                          
 244     // How long to wait before the new-shortcut animation automatically pans the workspace               
 245     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 246     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 247     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                    
 248                                                                                                          
 249     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 250             = new CloseSystemDialogsIntentReceiver();                                                    
 251     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 252                                                                                                          
 253     private LayoutInflater mInflater;                                                                    
 254                                                                                                          
 255     @Thunk Workspace mWorkspace;                                                                         
 256     private View mLauncherView;                                                                          
 257     private View mPageIndicators;                                                                        
 258     @Thunk DragLayer mDragLayer;                                                                         
 259     private DragController mDragController;                                                              
 260     private View mWeightWatcher;                                                                         
 261                                                                                                          
 262     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 263     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 264                                                                                                          
 265     @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                    
 266     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 267     private int mPendingAddWidgetId = -1;                                                                
 268                                                                                                          
 269     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 270                                                                                                          
 271     private Hotseat mHotseat;                                                                            
 272     private ViewGroup mOverviewPanel;                                                                    
 273                                                                                                          
 274     private View mAllAppsButton;                                                                         
 275                                                                                                          
 276     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 277                                                                                                          
 278     // Main container view for the all apps screen.                                                      
 279     @Thunk AllAppsContainerView mAppsView;                                                               
 280                                                                                                          
 281     // Main container view and the model for the widget tray screen.                                     
 282     @Thunk WidgetsContainerView mWidgetsView;                                                            
 283     @Thunk WidgetsModel mWidgetsModel;                                                                   
 284                                                                                                          
 285     private boolean mAutoAdvanceRunning = false;                                                         
 286     private AppWidgetHostView mQsb;                                                                      
 287                                                                                                          
 288     private Bundle mSavedState;                                                                          
 289     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 290     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 291     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 292     private State mOnResumeState = State.NONE;                                                           
 293                                                                                                          
 294     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 295                                                                                                          
 296     @Thunk boolean mWorkspaceLoading = true;                                                             
 297                                                                                                          
 298     private boolean mPaused = true;                                                                      
 299     private boolean mRestoring;                                                                          
 300     private boolean mWaitingForResult;                                                                   
 301     private boolean mOnResumeNeedsLoad;                                                                  
 302                                                                                                          
 303     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 304     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 305                                                                                                          
 306     private Bundle mSavedInstanceState;                                                                  
 307                                                                                                          
 308     private LauncherModel mModel;                                                                        
 309     private IconCache mIconCache;                                                                        
 310     @Thunk boolean mUserPresent = true;                                                                  
 311     private boolean mVisible = false;                                                                    
 312     private boolean mHasFocus = false;                                                                   
 313     private boolean mAttached = false;                                                                   
 314                                                                                                          
 315     @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                       
 316                                                                                                          
 317     private static LongArrayMap<FolderInfo> sFolders = new LongArrayMap<>();                             
 318                                                                                                          
 319     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 320                                                                                                          
 321     // Related to the auto-advancing of widgets                                                          
 322     private final int ADVANCE_MSG = 1;                                                                   
 323     private final int mAdvanceInterval = 20000;                                                          
 324     private final int mAdvanceStagger = 250;                                                             
 325     private long mAutoAdvanceSentTime;                                                                   
 326     private long mAutoAdvanceTimeLeft = -1;                                                              
 327     @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                      
 328         new HashMap<View, AppWidgetProviderInfo>();                                                      
 329                                                                                                          
 330     // Determines how long to wait after a rotation before restoring the screen orientation to           
 331     // match the sensor state.                                                                           
 332     private final int mRestoreScreenOrientationDelay = 500;                                              
 333                                                                                                          
 334     @Thunk Drawable mWorkspaceBackgroundDrawable;                                                        
 335                                                                                                          
 336     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 337     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 338                                                                                                          
 339     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 340     static Date sDateStamp = new Date();                                                                 
 341     static DateFormat sDateFormat =                                                                      
 342             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 343     static long sRunStart = System.currentTimeMillis();                                                  
 344     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 345                                                                                                          
 346     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 347     // it from the context.                                                                              
 348     private SharedPreferences mSharedPrefs;                                                              
 349                                                                                                          
 350     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 351     // when we scroll to that page on resume.                                                            
 352     @Thunk ImageView mFolderIconImageView;                                                               
 353     private Bitmap mFolderIconBitmap;                                                                    
 354     private Canvas mFolderIconCanvas;                                                                    
 355     private Rect mRectForFolderAnimation = new Rect();                                                   
 356                                                                                                          
 357     private DeviceProfile mDeviceProfile;                                                                
 358                                                                                                          
 359     // This is set to the view that launched the activity that navigated the user away from              
 360     // launcher. Since there is no callback for when the activity has finished launching, enable         
 361     // the press state and keep this reference to reset the press state when we return to launcher.      
 362     private BubbleTextView mWaitingForResume;                                                            
 363                                                                                                          
 364     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 365             new HashMap<String, CustomAppWidget>();                                                      
 366                                                                                                          
 367     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 368                                                                                                          
 369     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 370     private static Method sClipRevealMethod = null;                                                      
 371     static {                                                                                             
 372         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 373         try {                                                                                            
 374             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 375                     View.class, int.class, int.class, int.class, int.class);                             
 376         } catch (Exception e) {                                                                          
 377             // Earlier version                                                                           
 378         }                                                                                                
 379     }                                                                                                    
 380     static {                                                                                             
 381         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 382             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 383         }                                                                                                
 384     }                                                                                                    
 385                                                                                                          
 386     @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                              
 387         public void run() {                                                                              
 388             if (mWorkspace != null) {                                                                    
 389                 mWorkspace.buildPageHardwareLayers();                                                    
 390             }                                                                                            
 391         }                                                                                                
 392     };                                                                                                   
 393                                                                                                          
 394     private static PendingAddArguments sPendingAddItem;                                                  
 395                                                                                                          
 396     @Thunk static class PendingAddArguments {                                                            
 397         int requestCode;                                                                                 
 398         Intent intent;                                                                                   
 399         long container;                                                                                  
 400         long screenId;                                                                                   
 401         int cellX;                                                                                       
 402         int cellY;                                                                                       
 403         int appWidgetId;                                                                                 
 404     }                                                                                                    
 405                                                                                                          
 406     private Stats mStats;                                                                                
 407                                                                                                          
 408     FocusIndicatorView mFocusHandler;                                                                    
 409                                                                                                          
 410     @Override                                                                                            
 411     protected void onCreate(Bundle savedInstanceState) {                                                 
 412         if (DEBUG_STRICT_MODE) {                                                                         
 413             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 414                     .detectDiskReads()                                                                   
 415                     .detectDiskWrites()                                                                  
 416                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 417                     .penaltyLog()                                                                        
 418                     .build());                                                                           
 419             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 420                     .detectLeakedSqlLiteObjects()                                                        
 421                     .detectLeakedClosableObjects()                                                       
 422                     .penaltyLog()                                                                        
 423                     .penaltyDeath()                                                                      
 424                     .build());                                                                           
 425         }                                                                                                
 426                                                                                                          
 427         if (mLauncherCallbacks != null) {                                                                
 428             mLauncherCallbacks.preOnCreate();                                                            
 429         }                                                                                                
 430                                                                                                          
 431         super.onCreate(savedInstanceState);                                                              
 432                                                                                                          
 433         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 434         LauncherAppState app = LauncherAppState.getInstance();                                           
 435         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 436                                                                                                          
 437         // Load configuration-specific DeviceProfile                                                     
 438         mDeviceProfile = getResources().getConfiguration().orientation                                   
 439                 == Configuration.ORIENTATION_LANDSCAPE ?                                                 
 440                         app.getInvariantDeviceProfile().landscapeProfile                                 
 441                             : app.getInvariantDeviceProfile().portraitProfile;                           
 442                                                                                                          
 443         // TODO: Move this to icon cache.                                                                
 444         Utilities.setIconSize(mDeviceProfile.iconSizePx);                                                
 445                                                                                                          
 446         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 447         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 448                 Context.MODE_PRIVATE);                                                                   
 449         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 450         mModel = app.setLauncher(this);                                                                  
 451         mIconCache = app.getIconCache();                                                                 
 452                                                                                                          
 453         mDragController = new DragController(this);                                                      
 454         mInflater = getLayoutInflater();                                                                 
 455         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 456                                                                                                          
 457         mStats = new Stats(this);                                                                        
 458                                                                                                          
 459         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 460                                                                                                          
 461         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 462         mAppWidgetHost.startListening();                                                                 
 463                                                                                                          
 464         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 465         // this also ensures that any synchronous binding below doesn't re-trigger another               
 466         // LauncherModel load.                                                                           
 467         mPaused = false;                                                                                 
 468                                                                                                          
 469         if (PROFILE_STARTUP) {                                                                           
 470             android.os.Debug.startMethodTracing(                                                         
 471                     Environment.getExternalStorageDirectory() + "/launcher");                            
 472         }                                                                                                
 473                                                                                                          
 474         checkForLocaleChange();                                                                          
 475         setContentView(R.layout.launcher);                                                               
 476                                                                                                          
 477         setupViews();                                                                                    
 478         mDeviceProfile.layout(this);                                                                     
 479                                                                                                          
 480         registerContentObservers();                                                                      
 481                                                                                                          
 482         lockAllApps();                                                                                   
 483                                                                                                          
 484         mSavedState = savedInstanceState;                                                                
 485         restoreState(mSavedState);                                                                       
 486                                                                                                          
 487         if (PROFILE_STARTUP) {                                                                           
 488             android.os.Debug.stopMethodTracing();                                                        
 489         }                                                                                                
 490                                                                                                          
 491         if (!mRestoring) {                                                                               
 492             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 493                 // If the user leaves launcher, then we should just load items asynchronously when       
 494                 // they return.                                                                          
 495                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                      
 496             } else {                                                                                     
 497                 // We only load the page synchronously if the user rotates (or triggers a                
 498                 // configuration change) while launcher is in the foreground                             
 499                 mModel.startLoader(mWorkspace.getRestorePage());                                         
 500             }                                                                                            
 501         }                                                                                                
 502                                                                                                          
 503         // For handling default keys                                                                     
 504         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 505         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 506                                                                                                          
 507         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 508         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 509                                                                                                          
 510         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 511         unlockScreenOrientation(true);                                                                   
 512                                                                                                          
 513         if (mLauncherCallbacks != null) {                                                                
 514             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 515             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 516                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 517                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 518                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 519                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 520                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 521             }                                                                                            
 522         }                                                                                                
 523                                                                                                          
 524         if (shouldShowIntroScreen()) {                                                                   
 525             showIntroScreen();                                                                           
 526         } else {                                                                                         
 527             showFirstRunActivity();                                                                      
 528             showFirstRunClings();                                                                        
 529         }                                                                                                
 530     }                                                                                                    
 531                                                                                                          
 532     private LauncherCallbacks mLauncherCallbacks;                                                        
 533                                                                                                          
 534     public void onPostCreate(Bundle savedInstanceState) {                                                
 535         super.onPostCreate(savedInstanceState);                                                          
 536         if (mLauncherCallbacks != null) {                                                                
 537             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 538         }                                                                                                
 539     }                                                                                                    
 540                                                                                                          
 541     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 542         mLauncherCallbacks = callbacks;                                                                  
 543         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 544             @Override                                                                                    
 545             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 546                 if (LOGD) {                                                                              
 547                     Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);                               
 548                 }                                                                                        
 549                 mAppsView.setFixedBounds(bounds);                                                        
 550                 mWidgetsView.setFixedBounds(bounds);                                                     
 551             }                                                                                            
 552                                                                                                          
 553             @Override                                                                                    
 554             public void dismissAllApps() {                                                               
 555                 if (!DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
 556                     // Dismiss All Apps if we aren't already paused/invisible                            
 557                     if (!mPaused) {                                                                      
 558                         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true,    
 559                                 null /* onCompleteRunnable */, false /* notifyLauncherCallbacks */);     
 560                     }                                                                                    
 561                 }                                                                                        
 562             }                                                                                            
 563         });                                                                                              
 564         return true;                                                                                     
 565     }                                                                                                    
 566                                                                                                          
 567     @Override                                                                                            
 568     public void onLauncherProviderChange() {                                                             
 569         if (mLauncherCallbacks != null) {                                                                
 570             mLauncherCallbacks.onLauncherProviderChange();                                               
 571         }                                                                                                
 572     }                                                                                                    
 573                                                                                                          
 574     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 575     protected boolean hasCustomContentToLeft() {                                                         
 576         if (mLauncherCallbacks != null) {                                                                
 577             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 578         }                                                                                                
 579         return false;                                                                                    
 580     }                                                                                                    
 581                                                                                                          
 582     /**                                                                                                  
 583      * To be overridden by subclasses to populate the custom content container and call                  
 584      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 585      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 586      */                                                                                                  
 587     protected void populateCustomContentContainer() {                                                    
 588         if (mLauncherCallbacks != null) {                                                                
 589             mLauncherCallbacks.populateCustomContentContainer();                                         
 590         }                                                                                                
 591     }                                                                                                    
 592                                                                                                          
 593     /**                                                                                                  
 594      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 595      * ensure the custom content page is added or removed if necessary.                                  
 596      */                                                                                                  
 597     protected void invalidateHasCustomContentToLeft() {                                                  
 598         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 599             // Not bound yet, wait for bindScreens to be called.                                         
 600             return;                                                                                      
 601         }                                                                                                
 602                                                                                                          
 603         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 604             // Create the custom content page and call the subclass to populate it.                      
 605             mWorkspace.createCustomContentContainer();                                                   
 606             populateCustomContentContainer();                                                            
 607         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 608             mWorkspace.removeCustomContentPage();                                                        
 609         }                                                                                                
 610     }                                                                                                    
 611                                                                                                          
 612     @Thunk void checkForLocaleChange() {                                                                 
 613         if (sLocaleConfiguration == null) {                                                              
 614             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 615                 @Override                                                                                
 616                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 617                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 618                     readConfiguration(Launcher.this, localeConfiguration);                               
 619                     return localeConfiguration;                                                          
 620                 }                                                                                        
 621                                                                                                          
 622                 @Override                                                                                
 623                 protected void onPostExecute(LocaleConfiguration result) {                               
 624                     sLocaleConfiguration = result;                                                       
 625                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 626                 }                                                                                        
 627             }.execute();                                                                                 
 628             return;                                                                                      
 629         }                                                                                                
 630                                                                                                          
 631         final Configuration configuration = getResources().getConfiguration();                           
 632                                                                                                          
 633         final String previousLocale = sLocaleConfiguration.locale;                                       
 634         final String locale = configuration.locale.toString();                                           
 635                                                                                                          
 636         final int previousMcc = sLocaleConfiguration.mcc;                                                
 637         final int mcc = configuration.mcc;                                                               
 638                                                                                                          
 639         final int previousMnc = sLocaleConfiguration.mnc;                                                
 640         final int mnc = configuration.mnc;                                                               
 641                                                                                                          
 642         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 643                                                                                                          
 644         if (localeChanged) {                                                                             
 645             sLocaleConfiguration.locale = locale;                                                        
 646             sLocaleConfiguration.mcc = mcc;                                                              
 647             sLocaleConfiguration.mnc = mnc;                                                              
 648                                                                                                          
 649             mIconCache.flush();                                                                          
 650                                                                                                          
 651             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 652             new AsyncTask<Void, Void, Void>() {                                                          
 653                 public Void doInBackground(Void ... args) {                                              
 654                     writeConfiguration(Launcher.this, localeConfiguration);                              
 655                     return null;                                                                         
 656                 }                                                                                        
 657             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 658         }                                                                                                
 659     }                                                                                                    
 660                                                                                                          
 661     @Thunk static class LocaleConfiguration {                                                            
 662         public String locale;                                                                            
 663         public int mcc = -1;                                                                             
 664         public int mnc = -1;                                                                             
 665     }                                                                                                    
 666                                                                                                          
 667     @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {           
 668         DataInputStream in = null;                                                                       
 669         try {                                                                                            
 670             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 671             configuration.locale = in.readUTF();                                                         
 672             configuration.mcc = in.readInt();                                                            
 673             configuration.mnc = in.readInt();                                                            
 674         } catch (FileNotFoundException e) {                                                              
 675             // Ignore                                                                                    
 676         } catch (IOException e) {                                                                        
 677             // Ignore                                                                                    
 678         } finally {                                                                                      
 679             if (in != null) {                                                                            
 680                 try {                                                                                    
 681                     in.close();                                                                          
 682                 } catch (IOException e) {                                                                
 683                     // Ignore                                                                            
 684                 }                                                                                        
 685             }                                                                                            
 686         }                                                                                                
 687     }                                                                                                    
 688                                                                                                          
 689     @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {          
 690         DataOutputStream out = null;                                                                     
 691         try {                                                                                            
 692             out = new DataOutputStream(context.openFileOutput(                                           
 693                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 694             out.writeUTF(configuration.locale);                                                          
 695             out.writeInt(configuration.mcc);                                                             
 696             out.writeInt(configuration.mnc);                                                             
 697             out.flush();                                                                                 
 698         } catch (FileNotFoundException e) {                                                              
 699             // Ignore                                                                                    
 700         } catch (IOException e) {                                                                        
 701             //noinspection ResultOfMethodCallIgnored                                                     
 702             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 703         } finally {                                                                                      
 704             if (out != null) {                                                                           
 705                 try {                                                                                    
 706                     out.close();                                                                         
 707                 } catch (IOException e) {                                                                
 708                     // Ignore                                                                            
 709                 }                                                                                        
 710             }                                                                                            
 711         }                                                                                                
 712     }                                                                                                    
 713                                                                                                          
 714     public Stats getStats() {                                                                            
 715         return mStats;                                                                                   
 716     }                                                                                                    
 717                                                                                                          
 718     public LayoutInflater getInflater() {                                                                
 719         return mInflater;                                                                                
 720     }                                                                                                    
 721                                                                                                          
 722     public boolean isDraggingEnabled() {                                                                 
 723         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 724         // that is subsequently removed from the workspace in startBinding().                            
 725         return !mModel.isLoadingWorkspace();                                                             
 726     }                                                                                                    
 727                                                                                                          
 728     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 729     public static int generateViewId() {                                                                 
 730         if (Build.VERSION.SDK_INT >= 17) {                                                               
 731             return View.generateViewId();                                                                
 732         } else {                                                                                         
 733             // View.generateViewId() is not available. The following fallback logic is a copy            
 734             // of its implementation.                                                                    
 735             for (;;) {                                                                                   
 736                 final int result = sNextGeneratedId.get();                                               
 737                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 738                 int newValue = result + 1;                                                               
 739                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 740                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 741                     return result;                                                                       
 742                 }                                                                                        
 743             }                                                                                            
 744         }                                                                                                
 745     }                                                                                                    
 746                                                                                                          
 747     public int getViewIdForItem(ItemInfo info) {                                                         
 748         // This cast is safe given the > 2B range for int.                                               
 749         int itemId = (int) info.id;                                                                      
 750         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 751             return mItemIdToViewId.get(itemId);                                                          
 752         }                                                                                                
 753         int viewId = generateViewId();                                                                   
 754         mItemIdToViewId.put(itemId, viewId);                                                             
 755         return viewId;                                                                                   
 756     }                                                                                                    
 757                                                                                                          
 758     /**                                                                                                  
 759      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 760      * a configuration step, this allows the proper animations to run after other transitions.           
 761      */                                                                                                  
 762     private long completeAdd(PendingAddArguments args) {                                                 
 763         long screenId = args.screenId;                                                                   
 764         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 765             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 766             // that the drop page actually exists.                                                       
 767             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 768         }                                                                                                
 769                                                                                                          
 770         switch (args.requestCode) {                                                                      
 771             case REQUEST_CREATE_SHORTCUT:                                                                
 772                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 773                         args.cellY);                                                                     
 774                 break;                                                                                   
 775             case REQUEST_CREATE_APPWIDGET:                                                               
 776                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 777                 break;                                                                                   
 778             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 779                 completeRestoreAppWidget(args.appWidgetId);                                              
 780                 break;                                                                                   
 781         }                                                                                                
 782         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 783         // if you turned the screen off and then back while in All Apps, Launcher would not              
 784         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 785         resetAddInfo();                                                                                  
 786         return screenId;                                                                                 
 787     }                                                                                                    
 788                                                                                                          
 789     private void handleActivityResult(                                                                   
 790             final int requestCode, final int resultCode, final Intent data) {                            
 791         // Reset the startActivity waiting flag                                                          
 792         setWaitingForResult(false);                                                                      
 793         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 794         mPendingAddWidgetId = -1;                                                                        
 795                                                                                                          
 796         Runnable exitSpringLoaded = new Runnable() {                                                     
 797             @Override                                                                                    
 798             public void run() {                                                                          
 799                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 800                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 801             }                                                                                            
 802         };                                                                                               
 803                                                                                                          
 804         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 805             final int appWidgetId = data != null ?                                                       
 806                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 807             if (resultCode == RESULT_CANCELED) {                                                         
 808                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 809                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 810                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 811             } else if (resultCode == RESULT_OK) {                                                        
 812                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 813                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 814             }                                                                                            
 815             return;                                                                                      
 816         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 817             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 818                 showWorkspace(false);                                                                    
 819             }                                                                                            
 820             return;                                                                                      
 821         }                                                                                                
 822                                                                                                          
 823         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 824                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 825                                                                                                          
 826         final boolean workspaceLocked = isWorkspaceLocked();                                             
 827         // We have special handling for widgets                                                          
 828         if (isWidgetDrop) {                                                                              
 829             final int appWidgetId;                                                                       
 830             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 831                     : -1;                                                                                
 832             if (widgetId < 0) {                                                                          
 833                 appWidgetId = pendingAddWidgetId;                                                        
 834             } else {                                                                                     
 835                 appWidgetId = widgetId;                                                                  
 836             }                                                                                            
 837                                                                                                          
 838             final int result;                                                                            
 839             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 840                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 841                         "returned from the widget configuration activity.");                             
 842                 result = RESULT_CANCELED;                                                                
 843                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 844                 final Runnable onComplete = new Runnable() {                                             
 845                     @Override                                                                            
 846                     public void run() {                                                                  
 847                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 848                     }                                                                                    
 849                 };                                                                                       
 850                 if (workspaceLocked) {                                                                   
 851                     // No need to remove the empty screen if we're mid-binding, as the                   
 852                     // the bind will not add the empty screen.                                           
 853                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 854                 } else {                                                                                 
 855                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 856                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 857                 }                                                                                        
 858             } else {                                                                                     
 859                 if (!workspaceLocked) {                                                                  
 860                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 861                         // When the screen id represents an actual screen (as opposed to a rank)         
 862                         // we make sure that the drop page actually exists.                              
 863                         mPendingAddInfo.screenId =                                                       
 864                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 865                     }                                                                                    
 866                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 867                                                                                                          
 868                     dropLayout.setDropPending(true);                                                     
 869                     final Runnable onComplete = new Runnable() {                                         
 870                         @Override                                                                        
 871                         public void run() {                                                              
 872                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 873                             dropLayout.setDropPending(false);                                            
 874                         }                                                                                
 875                     };                                                                                   
 876                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 877                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 878                 } else {                                                                                 
 879                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 880                             mPendingAddInfo);                                                            
 881                     sPendingAddItem = args;                                                              
 882                 }                                                                                        
 883             }                                                                                            
 884             return;                                                                                      
 885         }                                                                                                
 886                                                                                                          
 887         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 888             if (resultCode == RESULT_OK) {                                                               
 889                 // Update the widget view.                                                               
 890                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 891                         pendingAddWidgetId, mPendingAddInfo);                                            
 892                 if (workspaceLocked) {                                                                   
 893                     sPendingAddItem = args;                                                              
 894                 } else {                                                                                 
 895                     completeAdd(args);                                                                   
 896                 }                                                                                        
 897             }                                                                                            
 898             // Leave the widget in the pending state if the user canceled the configure.                 
 899             return;                                                                                      
 900         }                                                                                                
 901                                                                                                          
 902         // The pattern used here is that a user PICKs a specific application,                            
 903         // which, depending on the target, might need to CREATE the actual target.                       
 904                                                                                                          
 905         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 906         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 907         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 908             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 909                     mPendingAddInfo);                                                                    
 910             if (isWorkspaceLocked()) {                                                                   
 911                 sPendingAddItem = args;                                                                  
 912             } else {                                                                                     
 913                 completeAdd(args);                                                                       
 914                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 915                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 916             }                                                                                            
 917         } else if (resultCode == RESULT_CANCELED) {                                                      
 918             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 919                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 920         }                                                                                                
 921         mDragLayer.clearAnimatedView();                                                                  
 922                                                                                                          
 923     }                                                                                                    
 924                                                                                                          
 925     @Override                                                                                            
 926     protected void onActivityResult(                                                                     
 927             final int requestCode, final int resultCode, final Intent data) {                            
 928         handleActivityResult(requestCode, resultCode, data);                                             
 929         if (mLauncherCallbacks != null) {                                                                
 930             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 931         }                                                                                                
 932     }                                                                                                    
 933                                                                                                          
 934     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 935             appWidgetId, ItemInfo info) {                                                                
 936         PendingAddArguments args = new PendingAddArguments();                                            
 937         args.requestCode = requestCode;                                                                  
 938         args.intent = data;                                                                              
 939         args.container = info.container;                                                                 
 940         args.screenId = info.screenId;                                                                   
 941         args.cellX = info.cellX;                                                                         
 942         args.cellY = info.cellY;                                                                         
 943         args.appWidgetId = appWidgetId;                                                                  
 944         return args;                                                                                     
 945     }                                                                                                    
 946                                                                                                          
 947     /**                                                                                                  
 948      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 949      *                                                                                                   
 950      * @param screenId the screen id to check                                                            
 951      * @return the new screen, or screenId if it exists                                                  
 952      */                                                                                                  
 953     private long ensurePendingDropLayoutExists(long screenId) {                                          
 954         CellLayout dropLayout =                                                                          
 955                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 956         if (dropLayout == null) {                                                                        
 957             // it's possible that the add screen was removed because it was                              
 958             // empty and a re-bind occurred                                                              
 959             mWorkspace.addExtraEmptyScreen();                                                            
 960             return mWorkspace.commitExtraEmptyScreen();                                                  
 961         } else {                                                                                         
 962             return screenId;                                                                             
 963         }                                                                                                
 964     }                                                                                                    
 965                                                                                                          
 966     @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                
 967         CellLayout cellLayout =                                                                          
 968                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 969         Runnable onCompleteRunnable = null;                                                              
 970         int animationType = 0;                                                                           
 971                                                                                                          
 972         AppWidgetHostView boundWidget = null;                                                            
 973         if (resultCode == RESULT_OK) {                                                                   
 974             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 975             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 976                     mPendingAddWidgetInfo);                                                              
 977             boundWidget = layout;                                                                        
 978             onCompleteRunnable = new Runnable() {                                                        
 979                 @Override                                                                                
 980                 public void run() {                                                                      
 981                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 982                             mPendingAddInfo.screenId, layout, null);                                     
 983                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 984                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 985                 }                                                                                        
 986             };                                                                                           
 987         } else if (resultCode == RESULT_CANCELED) {                                                      
 988             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 989             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 990         }                                                                                                
 991         if (mDragLayer.getAnimatedView() != null) {                                                      
 992             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 993                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 994                     animationType, boundWidget, true);                                                   
 995         } else if (onCompleteRunnable != null) {                                                         
 996             // The animated view may be null in the case of a rotation during widget configuration       
 997             onCompleteRunnable.run();                                                                    
 998         }                                                                                                
 999     }                                                                                                    
1000                                                                                                          
1001     @Override                                                                                            
1002     protected void onStop() {                                                                            
1003         super.onStop();                                                                                  
1004         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1005                                                                                                          
1006         if (mLauncherCallbacks != null) {                                                                
1007             mLauncherCallbacks.onStop();                                                                 
1008         }                                                                                                
1009     }                                                                                                    
1010                                                                                                          
1011     @Override                                                                                            
1012     protected void onStart() {                                                                           
1013         super.onStart();                                                                                 
1014         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1015                                                                                                          
1016         if (mLauncherCallbacks != null) {                                                                
1017             mLauncherCallbacks.onStart();                                                                
1018         }                                                                                                
1019     }                                                                                                    
1020                                                                                                          
1021     @Override                                                                                            
1022     protected void onResume() {                                                                          
1023         long startTime = 0;                                                                              
1024         if (DEBUG_RESUME_TIME) {                                                                         
1025             startTime = System.currentTimeMillis();                                                      
1026             Log.v(TAG, "Launcher.onResume()");                                                           
1027         }                                                                                                
1028                                                                                                          
1029         if (mLauncherCallbacks != null) {                                                                
1030             mLauncherCallbacks.preOnResume();                                                            
1031         }                                                                                                
1032                                                                                                          
1033         super.onResume();                                                                                
1034                                                                                                          
1035         // Restore the previous launcher state                                                           
1036         if (mOnResumeState == State.WORKSPACE) {                                                         
1037             showWorkspace(false);                                                                        
1038         } else if (mOnResumeState == State.APPS) {                                                       
1039             boolean launchedFromApp = (mWaitingForResume != null);                                       
1040             // Don't update the predicted apps if the user is returning to launcher in the apps          
1041             // view after launching an app, as they may be depending on the UI to be static to           
1042             // switch to another app, otherwise, if it was                                               
1043             showAppsView(false /* animated */, false /* resetListToTop */,                               
1044                     !launchedFromApp /* updatePredictedApps */);                                         
1045         } else if (mOnResumeState == State.WIDGETS) {                                                    
1046             showWidgetsView(false, false);                                                               
1047         }                                                                                                
1048         mOnResumeState = State.NONE;                                                                     
1049                                                                                                          
1050         // Restore the apps state if we are in all apps                                                  
1051         if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                             
1052             // Otherwise, notify the callbacks if we are in all apps mode                                
1053             if (mState == State.APPS) {                                                                  
1054                 if (mLauncherCallbacks != null) {                                                        
1055                     mLauncherCallbacks.onAllAppsShown();                                                 
1056                 }                                                                                        
1057             }                                                                                            
1058         }                                                                                                
1059                                                                                                          
1060         // Background was set to gradient in onPause(), restore to transparent if in all apps.           
1061         setWorkspaceBackground(mState == State.WORKSPACE ? WORKSPACE_BACKGROUND_TRANSPARENT              
1062                 : WORKSPACE_BACKGROUND_GRADIENT);                                                        
1063                                                                                                          
1064         mPaused = false;                                                                                 
1065         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1066             setWorkspaceLoading(true);                                                                   
1067             mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                          
1068             mRestoring = false;                                                                          
1069             mOnResumeNeedsLoad = false;                                                                  
1070         }                                                                                                
1071         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1072             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1073             // execute them here                                                                         
1074             long startTimeCallbacks = 0;                                                                 
1075             if (DEBUG_RESUME_TIME) {                                                                     
1076                 startTimeCallbacks = System.currentTimeMillis();                                         
1077             }                                                                                            
1078                                                                                                          
1079             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1080                 mBindOnResumeCallbacks.get(i).run();                                                     
1081             }                                                                                            
1082             mBindOnResumeCallbacks.clear();                                                              
1083             if (DEBUG_RESUME_TIME) {                                                                     
1084                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1085                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1086             }                                                                                            
1087         }                                                                                                
1088         if (mOnResumeCallbacks.size() > 0) {                                                             
1089             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1090                 mOnResumeCallbacks.get(i).run();                                                         
1091             }                                                                                            
1092             mOnResumeCallbacks.clear();                                                                  
1093         }                                                                                                
1094                                                                                                          
1095         // Reset the pressed state of icons that were locked in the press state while activities         
1096         // were launching                                                                                
1097         if (mWaitingForResume != null) {                                                                 
1098             // Resets the previous workspace icon press state                                            
1099             mWaitingForResume.setStayPressed(false);                                                     
1100         }                                                                                                
1101                                                                                                          
1102         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1103         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1104         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1105         // orientation.                                                                                  
1106         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1107         reinflateQSBIfNecessary();                                                                       
1108                                                                                                          
1109         if (DEBUG_RESUME_TIME) {                                                                         
1110             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1111         }                                                                                                
1112                                                                                                          
1113         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1114             // If we are resuming and the custom content is the current page, we call onShow().          
1115             // It is also poassible that onShow will instead be called slightly after first layout       
1116             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1117             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1118                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1119             }                                                                                            
1120         }                                                                                                
1121         updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());                                
1122         mWorkspace.onResume();                                                                           
1123                                                                                                          
1124         if (!isWorkspaceLoading()) {                                                                     
1125             // Process any items that were added while Launcher was away.                                
1126             InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                   
1127         }                                                                                                
1128                                                                                                          
1129         if (mLauncherCallbacks != null) {                                                                
1130             mLauncherCallbacks.onResume();                                                               
1131         }                                                                                                
1132     }                                                                                                    
1133                                                                                                          
1134     @Override                                                                                            
1135     protected void onPause() {                                                                           
1136         // Ensure that items added to Launcher are queued until Launcher returns                         
1137         InstallShortcutReceiver.enableInstallQueue();                                                    
1138                                                                                                          
1139         super.onPause();                                                                                 
1140         mPaused = true;                                                                                  
1141         mDragController.cancelDrag();                                                                    
1142         mDragController.resetLastGestureUpTime();                                                        
1143                                                                                                          
1144         // We call onHide() aggressively. The custom content callbacks should be able to                 
1145         // debounce excess onHide calls.                                                                 
1146         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1147             mWorkspace.getCustomContentCallbacks().onHide();                                             
1148         }                                                                                                
1149                                                                                                          
1150         if (mLauncherCallbacks != null) {                                                                
1151             mLauncherCallbacks.onPause();                                                                
1152         }                                                                                                
1153     }                                                                                                    
1154                                                                                                          
1155     public interface CustomContentCallbacks {                                                            
1156         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1157         // by a onResume or by scrolling otherwise.                                                      
1158         public void onShow(boolean fromResume);                                                          
1159                                                                                                          
1160         // Custom content is completely hidden                                                           
1161         public void onHide();                                                                            
1162                                                                                                          
1163         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1164         public void onScrollProgressChanged(float progress);                                             
1165                                                                                                          
1166         // Indicates whether the user is allowed to scroll away from the custom content.                 
1167         boolean isScrollingAllowed();                                                                    
1168     }                                                                                                    
1169                                                                                                          
1170     public interface LauncherOverlay {                                                                   
1171                                                                                                          
1172         /**                                                                                              
1173          * Touch interaction leading to overscroll has begun                                             
1174          */                                                                                              
1175         public void onScrollInteractionBegin();                                                          
1176                                                                                                          
1177         /**                                                                                              
1178          * Touch interaction related to overscroll has ended                                             
1179          */                                                                                              
1180         public void onScrollInteractionEnd();                                                            
1181                                                                                                          
1182         /**                                                                                              
1183          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1184          * screen (or in the case of RTL, the rightmost screen).                                         
1185          */                                                                                              
1186         public void onScrollChange(int progress, boolean rtl);                                           
1187                                                                                                          
1188         /**                                                                                              
1189          * Screen has stopped scrolling                                                                  
1190          */                                                                                              
1191         public void onScrollSettled();                                                                   
1192                                                                                                          
1193         /**                                                                                              
1194          * This method can be called by the Launcher in order to force the LauncherOverlay               
1195          * to exit fully immersive mode.                                                                 
1196          */                                                                                              
1197         public void forceExitFullImmersion();                                                            
1198     }                                                                                                    
1199                                                                                                          
1200     public interface LauncherAppsCallbacks {                                                             
1201         /**                                                                                              
1202          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1203          * any other views.                                                                              
1204          */                                                                                              
1205         public void onAllAppsBoundsChanged(Rect bounds);                                                 
1206                                                                                                          
1207         /**                                                                                              
1208          * Called to dismiss all apps if it is showing.                                                  
1209          */                                                                                              
1210         public void dismissAllApps();                                                                    
1211     }                                                                                                    
1212                                                                                                          
1213     public interface LauncherOverlayCallbacks {                                                          
1214         /**                                                                                              
1215          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1216          * however it doesn't modify any state within the launcher.                                      
1217          */                                                                                              
1218         public boolean canEnterFullImmersion();                                                          
1219                                                                                                          
1220         /**                                                                                              
1221          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1222          * eg. by occupying the full screen and handling all touch events.                               
1223          *                                                                                               
1224          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1225          *          case, Launcher will modify any necessary state and assumes the overlay is            
1226          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1227          *                                                                                               
1228          */                                                                                              
1229         public boolean enterFullImmersion();                                                             
1230                                                                                                          
1231         /**                                                                                              
1232          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1233          * full control over UI and state.                                                               
1234          */                                                                                              
1235         public void exitFullImmersion();                                                                 
1236     }                                                                                                    
1237                                                                                                          
1238     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1239                                                                                                          
1240         @Override                                                                                        
1241         public boolean canEnterFullImmersion() {                                                         
1242             return mState == State.WORKSPACE;                                                            
1243         }                                                                                                
1244                                                                                                          
1245         @Override                                                                                        
1246         public boolean enterFullImmersion() {                                                            
1247             if (mState == State.WORKSPACE) {                                                             
1248                 // When fully immersed, disregard any touches which fall through.                        
1249                 mDragLayer.setBlockTouch(true);                                                          
1250                 return true;                                                                             
1251             }                                                                                            
1252             return false;                                                                                
1253         }                                                                                                
1254                                                                                                          
1255         @Override                                                                                        
1256         public void exitFullImmersion() {                                                                
1257             mDragLayer.setBlockTouch(false);                                                             
1258         }                                                                                                
1259     }                                                                                                    
1260                                                                                                          
1261     protected boolean hasSettings() {                                                                    
1262         if (mLauncherCallbacks != null) {                                                                
1263             return mLauncherCallbacks.hasSettings();                                                     
1264         }                                                                                                
1265         return false;                                                                                    
1266     }                                                                                                    
1267                                                                                                          
1268     public void addToCustomContentPage(View customContent,                                               
1269             CustomContentCallbacks callbacks, String description) {                                      
1270         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1271     }                                                                                                    
1272                                                                                                          
1273     // The custom content needs to offset its content to account for the QSB                             
1274     public int getTopOffsetForCustomContent() {                                                          
1275         return mWorkspace.getPaddingTop();                                                               
1276     }                                                                                                    
1277                                                                                                          
1278     @Override                                                                                            
1279     public Object onRetainNonConfigurationInstance() {                                                   
1280         // Flag the loader to stop early before switching                                                
1281         if (mModel.isCurrentCallbacks(this)) {                                                           
1282             mModel.stopLoader();                                                                         
1283         }                                                                                                
1284         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1285                                                                                                          
1286         return Boolean.TRUE;                                                                             
1287     }                                                                                                    
1288                                                                                                          
1289     // We can't hide the IME if it was forced open.  So don't bother                                     
1290     @Override                                                                                            
1291     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1292         super.onWindowFocusChanged(hasFocus);                                                            
1293         mHasFocus = hasFocus;                                                                            
1294                                                                                                          
1295         if (mLauncherCallbacks != null) {                                                                
1296             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1297         }                                                                                                
1298     }                                                                                                    
1299                                                                                                          
1300     private boolean acceptFilter() {                                                                     
1301         final InputMethodManager inputManager = (InputMethodManager)                                     
1302                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1303         return !inputManager.isFullscreenMode();                                                         
1304     }                                                                                                    
1305                                                                                                          
1306     @Override                                                                                            
1307     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1308         final int uniChar = event.getUnicodeChar();                                                      
1309         final boolean handled = super.onKeyDown(keyCode, event);                                         
1310         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1311         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1312             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1313                     keyCode, event);                                                                     
1314             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1315                 // something usable has been typed - start a search                                      
1316                 // the typed text will be retrieved and cleared by                                       
1317                 // showSearchDialog()                                                                    
1318                 // If there are multiple keystrokes before the search dialog takes focus,                
1319                 // onSearchRequested() will be called for every keystroke,                               
1320                 // but it is idempotent, so it's fine.                                                   
1321                 return onSearchRequested();                                                              
1322             }                                                                                            
1323         }                                                                                                
1324                                                                                                          
1325         // Eat the long press event so the keyboard doesn't come up.                                     
1326         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1327             return true;                                                                                 
1328         }                                                                                                
1329                                                                                                          
1330         return handled;                                                                                  
1331     }                                                                                                    
1332                                                                                                          
1333     private String getTypedText() {                                                                      
1334         return mDefaultKeySsb.toString();                                                                
1335     }                                                                                                    
1336                                                                                                          
1337     private void clearTypedText() {                                                                      
1338         mDefaultKeySsb.clear();                                                                          
1339         mDefaultKeySsb.clearSpans();                                                                     
1340         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1341     }                                                                                                    
1342                                                                                                          
1343     /**                                                                                                  
1344      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1345      * State                                                                                             
1346      */                                                                                                  
1347     private static State intToState(int stateOrdinal) {                                                  
1348         State state = State.WORKSPACE;                                                                   
1349         final State[] stateValues = State.values();                                                      
1350         for (int i = 0; i < stateValues.length; i++) {                                                   
1351             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1352                 state = stateValues[i];                                                                  
1353                 break;                                                                                   
1354             }                                                                                            
1355         }                                                                                                
1356         return state;                                                                                    
1357     }                                                                                                    
1358                                                                                                          
1359     /**                                                                                                  
1360      * Restores the previous state, if it exists.                                                        
1361      *                                                                                                   
1362      * @param savedState The previous state.                                                             
1363      */                                                                                                  
1364     @SuppressWarnings("unchecked")                                                                       
1365     private void restoreState(Bundle savedState) {                                                       
1366         if (savedState == null) {                                                                        
1367             return;                                                                                      
1368         }                                                                                                
1369                                                                                                          
1370         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1371         if (state == State.APPS || state == State.WIDGETS) {                                             
1372             mOnResumeState = state;                                                                      
1373         }                                                                                                
1374                                                                                                          
1375         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1376                 PagedView.INVALID_RESTORE_PAGE);                                                         
1377         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1378             mWorkspace.setRestorePage(currentScreen);                                                    
1379         }                                                                                                
1380                                                                                                          
1381         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1382         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1383                                                                                                          
1384         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1385             mPendingAddInfo.container = pendingAddContainer;                                             
1386             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1387             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1388             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1389             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1390             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1391             AppWidgetProviderInfo info = savedState.getParcelable(                                       
1392                     RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                              
1393             mPendingAddWidgetInfo = info == null ?                                                       
1394                     null : LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                   
1395                                                                                                          
1396             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1397             setWaitingForResult(true);                                                                   
1398             mRestoring = true;                                                                           
1399         }                                                                                                
1400                                                                                                          
1401         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1402                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1403     }                                                                                                    
1404                                                                                                          
1405     /**                                                                                                  
1406      * Finds all the views we need and configure them properly.                                          
1407      */                                                                                                  
1408     private void setupViews() {                                                                          
1409         final DragController dragController = mDragController;                                           
1410                                                                                                          
1411         mLauncherView = findViewById(R.id.launcher);                                                     
1412         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1413         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1414         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1415         mWorkspace.setPageSwitchListener(this);                                                          
1416         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1417                                                                                                          
1418         mLauncherView.setSystemUiVisibility(                                                             
1419                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1420         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1421                                                                                                          
1422         // Setup the drag layer                                                                          
1423         mDragLayer.setup(this, dragController);                                                          
1424                                                                                                          
1425         // Setup the hotseat                                                                             
1426         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1427         if (mHotseat != null) {                                                                          
1428             mHotseat.setOnLongClickListener(this);                                                       
1429         }                                                                                                
1430                                                                                                          
1431         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1432         View widgetButton = findViewById(R.id.widget_button);                                            
1433         widgetButton.setOnClickListener(new OnClickListener() {                                          
1434             @Override                                                                                    
1435             public void onClick(View arg0) {                                                             
1436                 if (!mWorkspace.isSwitchingState()) {                                                    
1437                     onClickAddWidgetButton(arg0);                                                        
1438                 }                                                                                        
1439             }                                                                                            
1440         });                                                                                              
1441         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1442                                                                                                          
1443         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1444         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1445             @Override                                                                                    
1446             public void onClick(View arg0) {                                                             
1447                 if (!mWorkspace.isSwitchingState()) {                                                    
1448                     onClickWallpaperPicker(arg0);                                                        
1449                 }                                                                                        
1450             }                                                                                            
1451         });                                                                                              
1452         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1453                                                                                                          
1454         View settingsButton = findViewById(R.id.settings_button);                                        
1455         if (hasSettings()) {                                                                             
1456             settingsButton.setOnClickListener(new OnClickListener() {                                    
1457                 @Override                                                                                
1458                 public void onClick(View arg0) {                                                         
1459                     if (!mWorkspace.isSwitchingState()) {                                                
1460                         onClickSettingsButton(arg0);                                                     
1461                     }                                                                                    
1462                 }                                                                                        
1463             });                                                                                          
1464             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1465         } else {                                                                                         
1466             settingsButton.setVisibility(View.GONE);                                                     
1467         }                                                                                                
1468                                                                                                          
1469         mOverviewPanel.setAlpha(0f);                                                                     
1470                                                                                                          
1471         // Setup the workspace                                                                           
1472         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1473         mWorkspace.setOnLongClickListener(this);                                                         
1474         mWorkspace.setup(dragController);                                                                
1475         dragController.addDragListener(mWorkspace);                                                      
1476                                                                                                          
1477         // Get the search/delete bar                                                                     
1478         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1479                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1480                                                                                                          
1481         // Setup Apps                                                                                    
1482         mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);                                 
1483         if (isAllAppsSearchOverridden()) {                                                               
1484             mAppsView.hideHeaderBar();                                                                   
1485         }                                                                                                
1486                                                                                                          
1487         // Setup AppsCustomize                                                                           
1488         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                           
1489                                                                                                          
1490         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1491         dragController.setDragScoller(mWorkspace);                                                       
1492         dragController.setScrollView(mDragLayer);                                                        
1493         dragController.setMoveTarget(mWorkspace);                                                        
1494         dragController.addDropTarget(mWorkspace);                                                        
1495         if (mSearchDropTargetBar != null) {                                                              
1496             mSearchDropTargetBar.setup(this, dragController);                                            
1497             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1498         }                                                                                                
1499                                                                                                          
1500         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1501             Log.v(TAG, "adding WeightWatcher");                                                          
1502             mWeightWatcher = new WeightWatcher(this);                                                    
1503             mWeightWatcher.setAlpha(0.5f);                                                               
1504             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1505                     new FrameLayout.LayoutParams(                                                        
1506                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1507                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1508                             Gravity.BOTTOM)                                                              
1509             );                                                                                           
1510                                                                                                          
1511             boolean show = shouldShowWeightWatcher();                                                    
1512             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1513         }                                                                                                
1514     }                                                                                                    
1515                                                                                                          
1516     /**                                                                                                  
1517      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1518      */                                                                                                  
1519     public void setAllAppsButton(View allAppsButton) {                                                   
1520         mAllAppsButton = allAppsButton;                                                                  
1521     }                                                                                                    
1522                                                                                                          
1523     public View getAllAppsButton() {                                                                     
1524         return mAllAppsButton;                                                                           
1525     }                                                                                                    
1526                                                                                                          
1527     /**                                                                                                  
1528      * Creates a view representing a shortcut.                                                           
1529      *                                                                                                   
1530      * @param info The data structure describing the shortcut.                                           
1531      */                                                                                                  
1532     View createShortcut(ShortcutInfo info) {                                                             
1533         return createShortcut((ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);     
1534     }                                                                                                    
1535                                                                                                          
1536     /**                                                                                                  
1537      * Creates a view representing a shortcut inflated from the specified resource.                      
1538      *                                                                                                   
1539      * @param parent The group the shortcut belongs to.                                                  
1540      * @param info The data structure describing the shortcut.                                           
1541      *                                                                                                   
1542      * @return A View inflated from layoutResId.                                                         
1543      */                                                                                                  
1544     public View createShortcut(ViewGroup parent, ShortcutInfo info) {                                    
1545         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(R.layout.app_icon,                  
1546                 parent, false);                                                                          
1547         favorite.applyFromShortcutInfo(info, mIconCache);                                                
1548         favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);                       
1549         favorite.setOnClickListener(this);                                                               
1550         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1551         return favorite;                                                                                 
1552     }                                                                                                    
1553                                                                                                          
1554     /**                                                                                                  
1555      * Add a shortcut to the workspace.                                                                  
1556      *                                                                                                   
1557      * @param data The intent describing the shortcut.                                                   
1558      * @param cellInfo The position on screen where to create the shortcut.                              
1559      */                                                                                                  
1560     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1561             int cellY) {                                                                                 
1562         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1563         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1564         CellLayout layout = getCellLayout(container, screenId);                                          
1565                                                                                                          
1566         ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(this, data);                      
1567         if (info == null) {                                                                              
1568             return;                                                                                      
1569         }                                                                                                
1570         final View view = createShortcut(info);                                                          
1571                                                                                                          
1572         boolean foundCellSpan = false;                                                                   
1573         // First we check if we already know the exact location where we want to add this item.          
1574         if (cellX >= 0 && cellY >= 0) {                                                                  
1575             cellXY[0] = cellX;                                                                           
1576             cellXY[1] = cellY;                                                                           
1577             foundCellSpan = true;                                                                        
1578                                                                                                          
1579             // If appropriate, either create a folder or add to an existing folder                       
1580             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1581                     true, null,null)) {                                                                  
1582                 return;                                                                                  
1583             }                                                                                            
1584             DragObject dragObject = new DragObject();                                                    
1585             dragObject.dragInfo = info;                                                                  
1586             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1587                     true)) {                                                                             
1588                 return;                                                                                  
1589             }                                                                                            
1590         } else if (touchXY != null) {                                                                    
1591             // when dragging and dropping, just find the closest free spot                               
1592             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1593             foundCellSpan = (result != null);                                                            
1594         } else {                                                                                         
1595             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1596         }                                                                                                
1597                                                                                                          
1598         if (!foundCellSpan) {                                                                            
1599             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1600             return;                                                                                      
1601         }                                                                                                
1602                                                                                                          
1603         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1604                                                                                                          
1605         if (!mRestoring) {                                                                               
1606             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1607                     isWorkspaceLocked());                                                                
1608         }                                                                                                
1609     }                                                                                                    
1610                                                                                                          
1611     private int[] getSpanForWidget(ComponentName component, int minWidth, int minHeight) {               
1612         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(this, component, null);              
1613         // We want to account for the extra amount of padding that we are adding to the widget           
1614         // to ensure that it gets the full amount of space that it has requested                         
1615         int requiredWidth = minWidth + padding.left + padding.right;                                     
1616         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1617         return CellLayout.rectToCell(this, requiredWidth, requiredHeight, null);                         
1618     }                                                                                                    
1619                                                                                                          
1620     public int[] getSpanForWidget(AppWidgetProviderInfo info) {                                          
1621         return getSpanForWidget(info.provider, info.minWidth, info.minHeight);                           
1622     }                                                                                                    
1623                                                                                                          
1624     public int[] getMinSpanForWidget(AppWidgetProviderInfo info) {                                       
1625         return getSpanForWidget(info.provider, info.minResizeWidth, info.minResizeHeight);               
1626     }                                                                                                    
1627                                                                                                          
1628     /**                                                                                                  
1629      * Add a widget to the workspace.                                                                    
1630      *                                                                                                   
1631      * @param appWidgetId The app widget id                                                              
1632      */                                                                                                  
1633     @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                     
1634             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1635                                                                                                          
1636         ItemInfo info = mPendingAddInfo;                                                                 
1637         if (appWidgetInfo == null) {                                                                     
1638             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1639                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1640         }                                                                                                
1641                                                                                                          
1642         if (appWidgetInfo.isCustomWidget) {                                                              
1643             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1644         }                                                                                                
1645                                                                                                          
1646         LauncherAppWidgetInfo launcherInfo;                                                              
1647         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1648         launcherInfo.spanX = info.spanX;                                                                 
1649         launcherInfo.spanY = info.spanY;                                                                 
1650         launcherInfo.minSpanX = info.minSpanX;                                                           
1651         launcherInfo.minSpanY = info.minSpanY;                                                           
1652         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1653                                                                                                          
1654         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1655                 container, screenId, info.cellX, info.cellY);                                            
1656                                                                                                          
1657         if (!mRestoring) {                                                                               
1658             if (hostView == null) {                                                                      
1659                 // Perform actual inflation because we're live                                           
1660                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1661                         appWidgetInfo);                                                                  
1662             } else {                                                                                     
1663                 // The AppWidgetHostView has already been inflated and instantiated                      
1664                 launcherInfo.hostView = hostView;                                                        
1665             }                                                                                            
1666             launcherInfo.hostView.setTag(launcherInfo);                                                  
1667             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1668             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1669                                                                                                          
1670             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1671                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1672                                                                                                          
1673             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1674         }                                                                                                
1675         resetAddInfo();                                                                                  
1676     }                                                                                                    
1677                                                                                                          
1678     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1679         @Override                                                                                        
1680         public void onReceive(Context context, Intent intent) {                                          
1681             final String action = intent.getAction();                                                    
1682             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1683                 mUserPresent = false;                                                                    
1684                 mDragLayer.clearAllResizeFrames();                                                       
1685                 updateAutoAdvanceState();                                                                
1686                                                                                                          
1687                 // Reset AllApps to its initial state only if we are not in the middle of                
1688                 // processing a multi-step drop                                                          
1689                 if (mAppsView != null && mWidgetsView != null &&                                         
1690                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1691                     showWorkspace(false);                                                                
1692                 }                                                                                        
1693             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1694                 mUserPresent = true;                                                                     
1695                 updateAutoAdvanceState();                                                                
1696             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1697                 mModel.resetLoadedState(false, true);                                                    
1698                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                       
1699                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1700             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1701                 mModel.resetLoadedState(false, true);                                                    
1702                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                       
1703                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1704                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1705             }                                                                                            
1706         }                                                                                                
1707     };                                                                                                   
1708                                                                                                          
1709     @Override                                                                                            
1710     public void onAttachedToWindow() {                                                                   
1711         super.onAttachedToWindow();                                                                      
1712                                                                                                          
1713         // Listen for broadcasts related to user-presence                                                
1714         final IntentFilter filter = new IntentFilter();                                                  
1715         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1716         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1717         // For handling managed profiles                                                                 
1718         if (ENABLE_DEBUG_INTENTS) {                                                                      
1719             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1720             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1721         }                                                                                                
1722         registerReceiver(mReceiver, filter);                                                             
1723         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1724         setupTransparentSystemBarsForLmp();                                                              
1725         mAttached = true;                                                                                
1726         mVisible = true;                                                                                 
1727     }                                                                                                    
1728                                                                                                          
1729     /**                                                                                                  
1730      * Sets up transparent navigation and status bars in LMP.                                            
1731      * This method is a no-op for other platform versions.                                               
1732      */                                                                                                  
1733     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1734     private void setupTransparentSystemBarsForLmp() {                                                    
1735         if (Utilities.isLmpOrAbove()) {                                                                  
1736             Window window = getWindow();                                                                 
1737             window.getAttributes().systemUiVisibility |=                                                 
1738                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1739                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1740                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1741             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1742                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1743             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1744             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1745             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1746         }                                                                                                
1747     }                                                                                                    
1748                                                                                                          
1749     @Override                                                                                            
1750     public void onDetachedFromWindow() {                                                                 
1751         super.onDetachedFromWindow();                                                                    
1752         mVisible = false;                                                                                
1753                                                                                                          
1754         if (mAttached) {                                                                                 
1755             unregisterReceiver(mReceiver);                                                               
1756             mAttached = false;                                                                           
1757         }                                                                                                
1758         updateAutoAdvanceState();                                                                        
1759     }                                                                                                    
1760                                                                                                          
1761     public void onWindowVisibilityChanged(int visibility) {                                              
1762         mVisible = visibility == View.VISIBLE;                                                           
1763         updateAutoAdvanceState();                                                                        
1764         // The following code used to be in onResume, but it turns out onResume is called when           
1765         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1766         // is a more appropriate event to handle                                                         
1767         if (mVisible) {                                                                                  
1768             if (!mWorkspaceLoading) {                                                                    
1769                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1770                 // We want to let Launcher draw itself at least once before we force it to build         
1771                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1772                 // apps is nice and speedy.                                                              
1773                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1774                     private boolean mStarted = false;                                                    
1775                     public void onDraw() {                                                               
1776                         if (mStarted) return;                                                            
1777                         mStarted = true;                                                                 
1778                         // We delay the layer building a bit in order to give                            
1779                         // other message processing a time to run.  In particular                        
1780                         // this avoids a delay in hiding the IME if it was                               
1781                         // currently shown, because doing that may involve                               
1782                         // some communication back with the app.                                         
1783                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1784                         final ViewTreeObserver.OnDrawListener listener = this;                           
1785                         mWorkspace.post(new Runnable() {                                                 
1786                                 public void run() {                                                      
1787                                     if (mWorkspace != null &&                                            
1788                                             mWorkspace.getViewTreeObserver() != null) {                  
1789                                         mWorkspace.getViewTreeObserver().                                
1790                                                 removeOnDrawListener(listener);                          
1791                                     }                                                                    
1792                                 }                                                                        
1793                             });                                                                          
1794                         return;                                                                          
1795                     }                                                                                    
1796                 });                                                                                      
1797             }                                                                                            
1798             clearTypedText();                                                                            
1799         }                                                                                                
1800     }                                                                                                    
1801                                                                                                          
1802     @Thunk void sendAdvanceMessage(long delay) {                                                         
1803         mHandler.removeMessages(ADVANCE_MSG);                                                            
1804         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1805         mHandler.sendMessageDelayed(msg, delay);                                                         
1806         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1807     }                                                                                                    
1808                                                                                                          
1809     @Thunk void updateAutoAdvanceState() {                                                               
1810         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1811         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1812             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1813             if (autoAdvanceRunning) {                                                                    
1814                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1815                 sendAdvanceMessage(delay);                                                               
1816             } else {                                                                                     
1817                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1818                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1819                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1820                 }                                                                                        
1821                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1822                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1823             }                                                                                            
1824         }                                                                                                
1825     }                                                                                                    
1826                                                                                                          
1827     private final Handler mHandler = new Handler() {                                                     
1828         @Override                                                                                        
1829         public void handleMessage(Message msg) {                                                         
1830             if (msg.what == ADVANCE_MSG) {                                                               
1831                 int i = 0;                                                                               
1832                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1833                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1834                     final int delay = mAdvanceStagger * i;                                               
1835                     if (v instanceof Advanceable) {                                                      
1836                        postDelayed(new Runnable() {                                                      
1837                            public void run() {                                                           
1838                                ((Advanceable) v).advance();                                              
1839                            }                                                                             
1840                        }, delay);                                                                        
1841                     }                                                                                    
1842                     i++;                                                                                 
1843                 }                                                                                        
1844                 sendAdvanceMessage(mAdvanceInterval);                                                    
1845             }                                                                                            
1846         }                                                                                                
1847     };                                                                                                   
1848                                                                                                          
1849     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1850         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1851         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1852         if (v instanceof Advanceable) {                                                                  
1853             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1854             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1855             updateAutoAdvanceState();                                                                    
1856         }                                                                                                
1857     }                                                                                                    
1858                                                                                                          
1859     void removeWidgetToAutoAdvance(View hostView) {                                                      
1860         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1861             mWidgetsToAdvance.remove(hostView);                                                          
1862             updateAutoAdvanceState();                                                                    
1863         }                                                                                                
1864     }                                                                                                    
1865                                                                                                          
1866     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1867         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1868         launcherInfo.hostView = null;                                                                    
1869     }                                                                                                    
1870                                                                                                          
1871     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1872         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1873         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1874     }                                                                                                    
1875                                                                                                          
1876     public DragLayer getDragLayer() {                                                                    
1877         return mDragLayer;                                                                               
1878     }                                                                                                    
1879                                                                                                          
1880     public AllAppsContainerView getAppsView() {                                                          
1881         return mAppsView;                                                                                
1882     }                                                                                                    
1883                                                                                                          
1884     public WidgetsContainerView getWidgetsView() {                                                       
1885         return mWidgetsView;                                                                             
1886     }                                                                                                    
1887                                                                                                          
1888     public Workspace getWorkspace() {                                                                    
1889         return mWorkspace;                                                                               
1890     }                                                                                                    
1891                                                                                                          
1892     public Hotseat getHotseat() {                                                                        
1893         return mHotseat;                                                                                 
1894     }                                                                                                    
1895                                                                                                          
1896     public ViewGroup getOverviewPanel() {                                                                
1897         return mOverviewPanel;                                                                           
1898     }                                                                                                    
1899                                                                                                          
1900     public SearchDropTargetBar getSearchBar() {                                                          
1901         return mSearchDropTargetBar;                                                                     
1902     }                                                                                                    
1903                                                                                                          
1904     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1905         return mAppWidgetHost;                                                                           
1906     }                                                                                                    
1907                                                                                                          
1908     public LauncherModel getModel() {                                                                    
1909         return mModel;                                                                                   
1910     }                                                                                                    
1911                                                                                                          
1912     protected SharedPreferences getSharedPrefs() {                                                       
1913         return mSharedPrefs;                                                                             
1914     }                                                                                                    
1915                                                                                                          
1916     public DeviceProfile getDeviceProfile() {                                                            
1917         return mDeviceProfile;                                                                           
1918     }                                                                                                    
1919                                                                                                          
1920     public void closeSystemDialogs() {                                                                   
1921         getWindow().closeAllPanels();                                                                    
1922                                                                                                          
1923         // Whatever we were doing is hereby canceled.                                                    
1924         setWaitingForResult(false);                                                                      
1925     }                                                                                                    
1926                                                                                                          
1927     @Override                                                                                            
1928     protected void onNewIntent(Intent intent) {                                                          
1929         long startTime = 0;                                                                              
1930         if (DEBUG_RESUME_TIME) {                                                                         
1931             startTime = System.currentTimeMillis();                                                      
1932         }                                                                                                
1933         super.onNewIntent(intent);                                                                       
1934                                                                                                          
1935         // Close the menu                                                                                
1936         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1937             // also will cancel mWaitingForResult.                                                       
1938             closeSystemDialogs();                                                                        
1939                                                                                                          
1940             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1941                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1942                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1943                                                                                                          
1944             if (mWorkspace == null) {                                                                    
1945                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1946                 return;                                                                                  
1947             }                                                                                            
1948             Folder openFolder = mWorkspace.getOpenFolder();                                              
1949             // In all these cases, only animate if we're already on home                                 
1950             mWorkspace.exitWidgetResizeMode();                                                           
1951                                                                                                          
1952             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1953                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1954             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1955                     openFolder == null && moveToDefaultScreen) {                                         
1956                 mWorkspace.moveToDefaultScreen(true);                                                    
1957             }                                                                                            
1958                                                                                                          
1959             closeFolder();                                                                               
1960             exitSpringLoadedDragMode();                                                                  
1961                                                                                                          
1962             // If we are already on home, then just animate back to the workspace,                       
1963             // otherwise, just wait until onResume to set the state back to Workspace                    
1964             if (alreadyOnHome) {                                                                         
1965         showWorkspace(true);                                                                             
1966             } else {                                                                                     
1967                 mOnResumeState = State.WORKSPACE;                                                        
1968             }                                                                                            
1969                                                                                                          
1970             final View v = getWindow().peekDecorView();                                                  
1971             if (v != null && v.getWindowToken() != null) {                                               
1972                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1973                         INPUT_METHOD_SERVICE);                                                           
1974                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1975             }                                                                                            
1976                                                                                                          
1977             // Reset the apps view                                                                       
1978             if (!alreadyOnHome && mAppsView != null) {                                                   
1979                 mAppsView.scrollToTop();                                                                 
1980             }                                                                                            
1981                                                                                                          
1982             // Reset the widgets view                                                                    
1983             if (!alreadyOnHome && mWidgetsView != null) {                                                
1984                 mWidgetsView.scrollToTop();                                                              
1985             }                                                                                            
1986                                                                                                          
1987             if (mLauncherCallbacks != null) {                                                            
1988                 mLauncherCallbacks.onHomeIntent();                                                       
1989             }                                                                                            
1990         }                                                                                                
1991                                                                                                          
1992         if (DEBUG_RESUME_TIME) {                                                                         
1993             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1994         }                                                                                                
1995                                                                                                          
1996         if (mLauncherCallbacks != null) {                                                                
1997             mLauncherCallbacks.onNewIntent(intent);                                                      
1998         }                                                                                                
1999     }                                                                                                    
2000                                                                                                          
2001     @Override                                                                                            
2002     public void onRestoreInstanceState(Bundle state) {                                                   
2003         super.onRestoreInstanceState(state);                                                             
2004         for (int page: mSynchronouslyBoundPages) {                                                       
2005             mWorkspace.restoreInstanceStateForChild(page);                                               
2006         }                                                                                                
2007     }                                                                                                    
2008                                                                                                          
2009     @Override                                                                                            
2010     protected void onSaveInstanceState(Bundle outState) {                                                
2011         if (mWorkspace.getChildCount() > 0) {                                                            
2012             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
2013                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
2014         }                                                                                                
2015         super.onSaveInstanceState(outState);                                                             
2016                                                                                                          
2017         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
2018         // We close any open folder since it will not be re-opened, and we need to make sure             
2019         // this state is reflected.                                                                      
2020         closeFolder();                                                                                   
2021                                                                                                          
2022         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
2023                 mWaitingForResult) {                                                                     
2024             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
2025             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
2026             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
2027             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
2028             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
2029             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
2030             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
2031             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2032         }                                                                                                
2033                                                                                                          
2034         // Save the current widgets tray?                                                                
2035         // TODO(hyunyoungs)                                                                              
2036         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2037                                                                                                          
2038         if (mLauncherCallbacks != null) {                                                                
2039             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2040         }                                                                                                
2041     }                                                                                                    
2042                                                                                                          
2043     @Override                                                                                            
2044     public void onDestroy() {                                                                            
2045         super.onDestroy();                                                                               
2046                                                                                                          
2047         // Remove all pending runnables                                                                  
2048         mHandler.removeMessages(ADVANCE_MSG);                                                            
2049         mHandler.removeMessages(0);                                                                      
2050         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2051                                                                                                          
2052         // Stop callbacks from LauncherModel                                                             
2053         LauncherAppState app = (LauncherAppState.getInstance());                                         
2054                                                                                                          
2055         // It's possible to receive onDestroy after a new Launcher activity has                          
2056         // been created. In this case, don't interfere with the new Launcher.                            
2057         if (mModel.isCurrentCallbacks(this)) {                                                           
2058             mModel.stopLoader();                                                                         
2059             app.setLauncher(null);                                                                       
2060         }                                                                                                
2061                                                                                                          
2062         try {                                                                                            
2063             mAppWidgetHost.stopListening();                                                              
2064         } catch (NullPointerException ex) {                                                              
2065             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2066         }                                                                                                
2067         mAppWidgetHost = null;                                                                           
2068                                                                                                          
2069         mWidgetsToAdvance.clear();                                                                       
2070                                                                                                          
2071         TextKeyListener.getInstance().release();                                                         
2072                                                                                                          
2073         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2074         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2075                                                                                                          
2076         mDragLayer.clearAllResizeFrames();                                                               
2077         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2078         mWorkspace.removeAllWorkspaceScreens();                                                          
2079         mWorkspace = null;                                                                               
2080         mDragController = null;                                                                          
2081                                                                                                          
2082         LauncherAnimUtils.onDestroyActivity();                                                           
2083                                                                                                          
2084         if (mLauncherCallbacks != null) {                                                                
2085             mLauncherCallbacks.onDestroy();                                                              
2086         }                                                                                                
2087     }                                                                                                    
2088                                                                                                          
2089     public DragController getDragController() {                                                          
2090         return mDragController;                                                                          
2091     }                                                                                                    
2092                                                                                                          
2093     @Override                                                                                            
2094     public void startActivityForResult(Intent intent, int requestCode) {                                 
2095         onStartForResult(requestCode);                                                                   
2096         super.startActivityForResult(intent, requestCode);                                               
2097     }                                                                                                    
2098                                                                                                          
2099     @Override                                                                                            
2100     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2101             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2102         onStartForResult(requestCode);                                                                   
2103         try {                                                                                            
2104             super.startIntentSenderForResult(intent, requestCode,                                        
2105                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2106         } catch (IntentSender.SendIntentException e) {                                                   
2107             throw new ActivityNotFoundException();                                                       
2108         }                                                                                                
2109     }                                                                                                    
2110                                                                                                          
2111     private void onStartForResult(int requestCode) {                                                     
2112         if (requestCode >= 0) {                                                                          
2113             setWaitingForResult(true);                                                                   
2114         }                                                                                                
2115     }                                                                                                    
2116                                                                                                          
2117     /**                                                                                                  
2118      * Indicates that we want global search for this activity by setting the globalSearch                
2119      * argument for {@link #startSearch} to true.                                                        
2120      */                                                                                                  
2121     @Override                                                                                            
2122     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2123             Bundle appSearchData, boolean globalSearch) {                                                
2124                                                                                                          
2125         if (initialQuery == null) {                                                                      
2126             // Use any text typed in the launcher as the initial query                                   
2127             initialQuery = getTypedText();                                                               
2128         }                                                                                                
2129         if (appSearchData == null) {                                                                     
2130             appSearchData = new Bundle();                                                                
2131             appSearchData.putString("source", "launcher-search");                                        
2132         }                                                                                                
2133         Rect sourceBounds = new Rect();                                                                  
2134         if (mSearchDropTargetBar != null) {                                                              
2135             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2136         }                                                                                                
2137                                                                                                          
2138         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2139                 appSearchData, sourceBounds);                                                            
2140         if (clearTextImmediately) {                                                                      
2141             clearTypedText();                                                                            
2142         }                                                                                                
2143                                                                                                          
2144         // We need to show the workspace after starting the search                                       
2145         showWorkspace(true);                                                                             
2146     }                                                                                                    
2147                                                                                                          
2148     /**                                                                                                  
2149      * Start a text search.                                                                              
2150      *                                                                                                   
2151      * @return {@code true} if the search will start immediately, so any further keypresses              
2152      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2153      * to buffer keypresses.                                                                             
2154      */                                                                                                  
2155     public boolean startSearch(String initialQuery,                                                      
2156             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2157         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2158             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2159                     sourceBounds);                                                                       
2160         }                                                                                                
2161                                                                                                          
2162         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2163                 appSearchData, sourceBounds);                                                            
2164         return false;                                                                                    
2165     }                                                                                                    
2166                                                                                                          
2167     /**                                                                                                  
2168      * Starts the global search activity. This code is a copied from SearchManager                       
2169      */                                                                                                  
2170     private void startGlobalSearch(String initialQuery,                                                  
2171             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2172         final SearchManager searchManager =                                                              
2173             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2174         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2175         if (globalSearchActivity == null) {                                                              
2176             Log.w(TAG, "No global search activity found.");                                              
2177             return;                                                                                      
2178         }                                                                                                
2179         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2180         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2181         intent.setComponent(globalSearchActivity);                                                       
2182         // Make sure that we have a Bundle to put source in                                              
2183         if (appSearchData == null) {                                                                     
2184             appSearchData = new Bundle();                                                                
2185         } else {                                                                                         
2186             appSearchData = new Bundle(appSearchData);                                                   
2187         }                                                                                                
2188         // Set source to package name of app that starts global search if not set already.               
2189         if (!appSearchData.containsKey("source")) {                                                      
2190             appSearchData.putString("source", getPackageName());                                         
2191         }                                                                                                
2192         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2193         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2194             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2195         }                                                                                                
2196         if (selectInitialQuery) {                                                                        
2197             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2198         }                                                                                                
2199         intent.setSourceBounds(sourceBounds);                                                            
2200         try {                                                                                            
2201             startActivity(intent);                                                                       
2202         } catch (ActivityNotFoundException ex) {                                                         
2203             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2204         }                                                                                                
2205     }                                                                                                    
2206                                                                                                          
2207     public boolean isOnCustomContent() {                                                                 
2208         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2209     }                                                                                                    
2210                                                                                                          
2211     @Override                                                                                            
2212     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2213         super.onPrepareOptionsMenu(menu);                                                                
2214         if (!isOnCustomContent()) {                                                                      
2215             // Close any open folders                                                                    
2216             closeFolder();                                                                               
2217             // Stop resizing any widgets                                                                 
2218             mWorkspace.exitWidgetResizeMode();                                                           
2219             if (!mWorkspace.isInOverviewMode()) {                                                        
2220                 // Show the overview mode                                                                
2221                 showOverviewMode(true);                                                                  
2222             } else {                                                                                     
2223                 showWorkspace(true);                                                                     
2224             }                                                                                            
2225         }                                                                                                
2226         if (mLauncherCallbacks != null) {                                                                
2227             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2228         }                                                                                                
2229                                                                                                          
2230         return false;                                                                                    
2231     }                                                                                                    
2232                                                                                                          
2233     @Override                                                                                            
2234     public boolean onSearchRequested() {                                                                 
2235         startSearch(null, false, null, true);                                                            
2236         // Use a custom animation for launching search                                                   
2237         return true;                                                                                     
2238     }                                                                                                    
2239                                                                                                          
2240     public boolean isWorkspaceLocked() {                                                                 
2241         return mWorkspaceLoading || mWaitingForResult;                                                   
2242     }                                                                                                    
2243                                                                                                          
2244     public boolean isWorkspaceLoading() {                                                                
2245         return mWorkspaceLoading;                                                                        
2246     }                                                                                                    
2247                                                                                                          
2248     private void setWorkspaceLoading(boolean value) {                                                    
2249         boolean isLocked = isWorkspaceLocked();                                                          
2250         mWorkspaceLoading = value;                                                                       
2251         if (isLocked != isWorkspaceLocked()) {                                                           
2252             onWorkspaceLockedChanged();                                                                  
2253         }                                                                                                
2254     }                                                                                                    
2255                                                                                                          
2256     private void setWaitingForResult(boolean value) {                                                    
2257         boolean isLocked = isWorkspaceLocked();                                                          
2258         mWaitingForResult = value;                                                                       
2259         if (isLocked != isWorkspaceLocked()) {                                                           
2260             onWorkspaceLockedChanged();                                                                  
2261         }                                                                                                
2262     }                                                                                                    
2263                                                                                                          
2264     protected void onWorkspaceLockedChanged() {                                                          
2265         if (mLauncherCallbacks != null) {                                                                
2266             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2267         }                                                                                                
2268     }                                                                                                    
2269                                                                                                          
2270     private void resetAddInfo() {                                                                        
2271         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2272         mPendingAddInfo.screenId = -1;                                                                   
2273         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2274         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2275         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2276         mPendingAddInfo.dropPos = null;                                                                  
2277     }                                                                                                    
2278                                                                                                          
2279     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2280             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2281         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2282     }                                                                                                    
2283                                                                                                          
2284     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2285             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2286             int delay) {                                                                                 
2287         if (appWidgetInfo.configure != null) {                                                           
2288             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2289             mPendingAddWidgetId = appWidgetId;                                                           
2290                                                                                                          
2291             // Launch over to configure widget, if needed                                                
2292             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2293                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2294                                                                                                          
2295         } else {                                                                                         
2296             // Otherwise just add it                                                                     
2297             Runnable onComplete = new Runnable() {                                                       
2298                 @Override                                                                                
2299                 public void run() {                                                                      
2300                     // Exit spring loaded mode if necessary after adding the widget                      
2301                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2302                             null);                                                                       
2303                 }                                                                                        
2304             };                                                                                           
2305             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2306                     appWidgetInfo);                                                                      
2307             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2308         }                                                                                                
2309     }                                                                                                    
2310                                                                                                          
2311     protected void moveToCustomContentScreen(boolean animate) {                                          
2312         // Close any folders that may be open.                                                           
2313         closeFolder();                                                                                   
2314         mWorkspace.moveToCustomContentScreen(animate);                                                   
2315     }                                                                                                    
2316                                                                                                          
2317     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2318             int[] cell, int spanX, int spanY) {                                                          
2319         switch (info.itemType) {                                                                         
2320             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2321             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2322                 int span[] = new int[2];                                                                 
2323                 span[0] = spanX;                                                                         
2324                 span[1] = spanY;                                                                         
2325                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2326                         container, screenId, cell, span);                                                
2327                 break;                                                                                   
2328             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2329                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2330                 break;                                                                                   
2331             default:                                                                                     
2332                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2333             }                                                                                            
2334     }                                                                                                    
2335                                                                                                          
2336     /**                                                                                                  
2337      * Process a shortcut drop.                                                                          
2338      *                                                                                                   
2339      * @param componentName The name of the component                                                    
2340      * @param screenId The ID of the screen where it should be added                                     
2341      * @param cell The cell it should be added to, optional                                              
2342      */                                                                                                  
2343     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2344             int[] cell) {                                                                                
2345         resetAddInfo();                                                                                  
2346         mPendingAddInfo.container = container;                                                           
2347         mPendingAddInfo.screenId = screenId;                                                             
2348         mPendingAddInfo.dropPos = null;                                                                  
2349                                                                                                          
2350         if (cell != null) {                                                                              
2351             mPendingAddInfo.cellX = cell[0];                                                             
2352             mPendingAddInfo.cellY = cell[1];                                                             
2353         }                                                                                                
2354                                                                                                          
2355         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2356         createShortcutIntent.setComponent(componentName);                                                
2357         processShortcut(createShortcutIntent);                                                           
2358     }                                                                                                    
2359                                                                                                          
2360     /**                                                                                                  
2361      * Process a widget drop.                                                                            
2362      *                                                                                                   
2363      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2364      * @param screenId The ID of the screen where it should be added                                     
2365      * @param cell The cell it should be added to, optional                                              
2366      */                                                                                                  
2367     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2368             int[] cell, int[] span) {                                                                    
2369         resetAddInfo();                                                                                  
2370         mPendingAddInfo.container = info.container = container;                                          
2371         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2372         mPendingAddInfo.dropPos = null;                                                                  
2373         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2374         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2375                                                                                                          
2376         if (cell != null) {                                                                              
2377             mPendingAddInfo.cellX = cell[0];                                                             
2378             mPendingAddInfo.cellY = cell[1];                                                             
2379         }                                                                                                
2380         if (span != null) {                                                                              
2381             mPendingAddInfo.spanX = span[0];                                                             
2382             mPendingAddInfo.spanY = span[1];                                                             
2383         }                                                                                                
2384                                                                                                          
2385         AppWidgetHostView hostView = info.boundWidget;                                                   
2386         int appWidgetId;                                                                                 
2387         if (hostView != null) {                                                                          
2388             appWidgetId = hostView.getAppWidgetId();                                                     
2389             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2390         } else {                                                                                         
2391             // In this case, we either need to start an activity to get permission to bind               
2392             // the widget, or we need to start an activity to configure the widget, or both.             
2393             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2394             Bundle options = info.bindOptions;                                                           
2395                                                                                                          
2396             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2397                     appWidgetId, info.info, options);                                                    
2398             if (success) {                                                                               
2399                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2400             } else {                                                                                     
2401                 mPendingAddWidgetInfo = info.info;                                                       
2402                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2403                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2404                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2405                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2406                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2407                 // TODO: we need to make sure that this accounts for the options bundle.                 
2408                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2409                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2410             }                                                                                            
2411         }                                                                                                
2412     }                                                                                                    
2413                                                                                                          
2414     void processShortcut(Intent intent) {                                                                
2415         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2416     }                                                                                                    
2417                                                                                                          
2418     void processWallpaper(Intent intent) {                                                               
2419         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2420     }                                                                                                    
2421                                                                                                          
2422     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2423             int cellY) {                                                                                 
2424         final FolderInfo folderInfo = new FolderInfo();                                                  
2425         folderInfo.title = getText(R.string.folder_name);                                                
2426                                                                                                          
2427         // Update the model                                                                              
2428         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                  
2429                 cellX, cellY);                                                                           
2430         sFolders.put(folderInfo.id, folderInfo);                                                         
2431                                                                                                          
2432         // Create the view                                                                               
2433         FolderIcon newFolder =                                                                           
2434             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2435         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2436                 isWorkspaceLocked());                                                                    
2437         // Force measure the new folder icon                                                             
2438         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2439         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2440         return newFolder;                                                                                
2441     }                                                                                                    
2442                                                                                                          
2443     void removeFolder(FolderInfo folder) {                                                               
2444         sFolders.remove(folder.id);                                                                      
2445     }                                                                                                    
2446                                                                                                          
2447     /**                                                                                                  
2448      * Registers various content observers. The current implementation registers                         
2449      * only a favorites observer to keep track of the favorites applications.                            
2450      */                                                                                                  
2451     private void registerContentObservers() {                                                            
2452         ContentResolver resolver = getContentResolver();                                                 
2453         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2454                 true, mWidgetObserver);                                                                  
2455     }                                                                                                    
2456                                                                                                          
2457     @Override                                                                                            
2458     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2459         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2460             switch (event.getKeyCode()) {                                                                
2461                 case KeyEvent.KEYCODE_HOME:                                                              
2462                     return true;                                                                         
2463                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2464                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2465                         dumpState();                                                                     
2466                         return true;                                                                     
2467                     }                                                                                    
2468                     break;                                                                               
2469             }                                                                                            
2470         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2471             switch (event.getKeyCode()) {                                                                
2472                 case KeyEvent.KEYCODE_HOME:                                                              
2473                     return true;                                                                         
2474             }                                                                                            
2475         }                                                                                                
2476                                                                                                          
2477         return super.dispatchKeyEvent(event);                                                            
2478     }                                                                                                    
2479                                                                                                          
2480     @Override                                                                                            
2481     public void onBackPressed() {                                                                        
2482         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2483             return;                                                                                      
2484         }                                                                                                
2485                                                                                                          
2486         LauncherAccessibilityDelegate delegate =                                                         
2487                 LauncherAppState.getInstance().getAccessibilityDelegate();                               
2488         if (delegate != null && delegate.onBackPressed()) {                                              
2489             return;                                                                                      
2490             }                                                                                            
2491                                                                                                          
2492         if (isAppsViewVisible()) {                                                                       
2493             showWorkspace(true);                                                                         
2494         } else if (isWidgetsViewVisible())  {                                                            
2495             showOverviewMode(true);                                                                      
2496         } else if (mWorkspace.isInOverviewMode()) {                                                      
2497             showWorkspace(true);                                                                         
2498         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2499             Folder openFolder = mWorkspace.getOpenFolder();                                              
2500             if (openFolder.isEditingName()) {                                                            
2501                 openFolder.dismissEditingName();                                                         
2502             } else {                                                                                     
2503                 closeFolder();                                                                           
2504             }                                                                                            
2505         } else {                                                                                         
2506             mWorkspace.exitWidgetResizeMode();                                                           
2507                                                                                                          
2508             // Back button is a no-op here, but give at least some feedback for the button press         
2509             mWorkspace.showOutlinesTemporarily();                                                        
2510         }                                                                                                
2511     }                                                                                                    
2512                                                                                                          
2513     /**                                                                                                  
2514      * Re-listen when widgets are reset.                                                                 
2515      */                                                                                                  
2516     @Thunk void onAppWidgetReset() {                                                                     
2517         if (mAppWidgetHost != null) {                                                                    
2518             mAppWidgetHost.startListening();                                                             
2519         }                                                                                                
2520     }                                                                                                    
2521                                                                                                          
2522     /**                                                                                                  
2523      * Launches the intent referred by the clicked shortcut.                                             
2524      *                                                                                                   
2525      * @param v The view representing the clicked shortcut.                                              
2526      */                                                                                                  
2527     public void onClick(View v) {                                                                        
2528         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2529         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2530         if (v.getWindowToken() == null) {                                                                
2531             return;                                                                                      
2532         }                                                                                                
2533                                                                                                          
2534         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2535             return;                                                                                      
2536         }                                                                                                
2537                                                                                                          
2538         if (v instanceof Workspace) {                                                                    
2539             if (mWorkspace.isInOverviewMode()) {                                                         
2540                 showWorkspace(true);                                                                     
2541             }                                                                                            
2542             return;                                                                                      
2543         }                                                                                                
2544                                                                                                          
2545         if (v instanceof CellLayout) {                                                                   
2546             if (mWorkspace.isInOverviewMode()) {                                                         
2547                 showWorkspace(mWorkspace.indexOfChild(v), true);                                         
2548             }                                                                                            
2549         }                                                                                                
2550                                                                                                          
2551         Object tag = v.getTag();                                                                         
2552         if (tag instanceof ShortcutInfo) {                                                               
2553             onClickAppShortcut(v);                                                                       
2554         } else if (tag instanceof FolderInfo) {                                                          
2555             if (v instanceof FolderIcon) {                                                               
2556                 onClickFolderIcon(v);                                                                    
2557             }                                                                                            
2558         } else if (v == mAllAppsButton) {                                                                
2559             onClickAllAppsButton(v);                                                                     
2560         } else if (tag instanceof AppInfo) {                                                             
2561             startAppShortcutOrInfoActivity(v);                                                           
2562         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2563             if (v instanceof PendingAppWidgetHostView) {                                                 
2564                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2565             }                                                                                            
2566         }                                                                                                
2567     }                                                                                                    
2568                                                                                                          
2569     public void onClickPagedViewIcon(View v) {                                                           
2570         startAppShortcutOrInfoActivity(v);                                                               
2571         if (mLauncherCallbacks != null) {                                                                
2572             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2573         }                                                                                                
2574     }                                                                                                    
2575                                                                                                          
2576     @SuppressLint("ClickableViewAccessibility")                                                          
2577 public boolean onTouch(View v, MotionEvent event) {                                                      
2578         return false;                                                                                    
2579     }                                                                                                    
2580                                                                                                          
2581     /**                                                                                                  
2582      * Event handler for the app widget view which has not fully restored.                               
2583      */                                                                                                  
2584     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2585         if (mIsSafeModeEnabled) {                                                                        
2586             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2587             return;                                                                                      
2588         }                                                                                                
2589                                                                                                          
2590         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2591         if (v.isReadyForClickSetup()) {                                                                  
2592             int widgetId = info.appWidgetId;                                                             
2593             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2594             if (appWidgetInfo != null) {                                                                 
2595                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2596                         this, appWidgetInfo);                                                            
2597                 mPendingAddInfo.copyFrom(info);                                                          
2598                 mPendingAddWidgetId = widgetId;                                                          
2599                                                                                                          
2600                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2601                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2602             }                                                                                            
2603         } else if (info.installProgress < 0) {                                                           
2604             // The install has not been queued                                                           
2605             final String packageName = info.providerName.getPackageName();                               
2606             showBrokenAppInstallDialog(packageName,                                                      
2607                 new DialogInterface.OnClickListener() {                                                  
2608                     public void onClick(DialogInterface dialog, int id) {                                
2609                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2610                     }                                                                                    
2611                 });                                                                                      
2612         } else {                                                                                         
2613             // Download has started.                                                                     
2614             final String packageName = info.providerName.getPackageName();                               
2615             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2616         }                                                                                                
2617     }                                                                                                    
2618                                                                                                          
2619     /**                                                                                                  
2620      * Event handler for the "grid" button that appears on the home screen, which                        
2621      * enters all apps mode.                                                                             
2622      *                                                                                                   
2623      * @param v The view that was clicked.                                                               
2624      */                                                                                                  
2625     protected void onClickAllAppsButton(View v) {                                                        
2626         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2627         if (isAppsViewVisible()) {                                                                       
2628             showWorkspace(true);                                                                         
2629         } else {                                                                                         
2630             // Try and refresh the set of predicted apps before we enter launcher                        
2631             showAppsView(true /* animated */, false /* resetListToTop */,                                
2632                     true /* updatePredictedApps */);                                                     
2633         }                                                                                                
2634     }                                                                                                    
2635                                                                                                          
2636     private void showBrokenAppInstallDialog(final String packageName,                                    
2637             DialogInterface.OnClickListener onSearchClickListener) {                                     
2638         new AlertDialog.Builder(this)                                                                    
2639             .setTitle(R.string.abandoned_promises_title)                                                 
2640             .setMessage(R.string.abandoned_promise_explanation)                                          
2641             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2642             .setNeutralButton(R.string.abandoned_clean_this,                                             
2643                 new DialogInterface.OnClickListener() {                                                  
2644                     public void onClick(DialogInterface dialog, int id) {                                
2645                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2646                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2647                     }                                                                                    
2648                 })                                                                                       
2649             .create().show();                                                                            
2650         return;                                                                                          
2651     }                                                                                                    
2652                                                                                                          
2653     /**                                                                                                  
2654      * Event handler for an app shortcut click.                                                          
2655      *                                                                                                   
2656      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2657      */                                                                                                  
2658     protected void onClickAppShortcut(final View v) {                                                    
2659         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2660         Object tag = v.getTag();                                                                         
2661         if (!(tag instanceof ShortcutInfo)) {                                                            
2662             throw new IllegalArgumentException("Input must be a Shortcut");                              
2663         }                                                                                                
2664                                                                                                          
2665         // Open shortcut                                                                                 
2666         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2667                                                                                                          
2668         if (shortcut.isDisabled != 0) {                                                                  
2669             int error = R.string.activity_not_available;                                                 
2670             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2671                 error = R.string.safemode_shortcut_error;                                                
2672             }                                                                                            
2673             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2674             return;                                                                                      
2675         }                                                                                                
2676                                                                                                          
2677         final Intent intent = shortcut.intent;                                                           
2678                                                                                                          
2679         // Check for special shortcuts                                                                   
2680         if (intent.getComponent() != null) {                                                             
2681             final String shortcutClass = intent.getComponent().getClassName();                           
2682                                                                                                          
2683             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2684                 MemoryDumpActivity.startDump(this);                                                      
2685                 return;                                                                                  
2686             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2687                 toggleShowWeightWatcher();                                                               
2688                 return;                                                                                  
2689             }                                                                                            
2690         }                                                                                                
2691                                                                                                          
2692         // Check for abandoned promise                                                                   
2693         if ((v instanceof BubbleTextView)                                                                
2694                 && shortcut.isPromise()                                                                  
2695                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2696             showBrokenAppInstallDialog(                                                                  
2697                     shortcut.getTargetComponent().getPackageName(),                                      
2698                     new DialogInterface.OnClickListener() {                                              
2699                         public void onClick(DialogInterface dialog, int id) {                            
2700                             startAppShortcutOrInfoActivity(v);                                           
2701                         }                                                                                
2702                     });                                                                                  
2703             return;                                                                                      
2704         }                                                                                                
2705                                                                                                          
2706         // Start activities                                                                              
2707         startAppShortcutOrInfoActivity(v);                                                               
2708                                                                                                          
2709         if (mLauncherCallbacks != null) {                                                                
2710             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2711         }                                                                                                
2712     }                                                                                                    
2713                                                                                                          
2714     @Thunk void startAppShortcutOrInfoActivity(View v) {                                                 
2715         Object tag = v.getTag();                                                                         
2716         final ShortcutInfo shortcut;                                                                     
2717         final Intent intent;                                                                             
2718         if (tag instanceof ShortcutInfo) {                                                               
2719             shortcut = (ShortcutInfo) tag;                                                               
2720             intent = shortcut.intent;                                                                    
2721             int[] pos = new int[2];                                                                      
2722             v.getLocationOnScreen(pos);                                                                  
2723             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2724                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2725                                                                                                          
2726         } else if (tag instanceof AppInfo) {                                                             
2727             shortcut = null;                                                                             
2728             intent = ((AppInfo) tag).intent;                                                             
2729         } else {                                                                                         
2730             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2731         }                                                                                                
2732                                                                                                          
2733         boolean success = startActivitySafely(v, intent, tag);                                           
2734         mStats.recordLaunch(intent, shortcut);                                                           
2735                                                                                                          
2736         if (success && v instanceof BubbleTextView) {                                                    
2737             mWaitingForResume = (BubbleTextView) v;                                                      
2738             mWaitingForResume.setStayPressed(true);                                                      
2739         }                                                                                                
2740     }                                                                                                    
2741                                                                                                          
2742     /**                                                                                                  
2743      * Event handler for a folder icon click.                                                            
2744      *                                                                                                   
2745      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2746      */                                                                                                  
2747     protected void onClickFolderIcon(View v) {                                                           
2748         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2749         if (!(v instanceof FolderIcon)){                                                                 
2750             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2751         }                                                                                                
2752                                                                                                          
2753         FolderIcon folderIcon = (FolderIcon) v;                                                          
2754         final FolderInfo info = folderIcon.getFolderInfo();                                              
2755         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2756                                                                                                          
2757         // If the folder info reports that the associated folder is open, then verify that               
2758         // it is actually opened. There have been a few instances where this gets out of sync.           
2759         if (info.opened && openFolder == null) {                                                         
2760             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2761                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2762             info.opened = false;                                                                         
2763         }                                                                                                
2764                                                                                                          
2765         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2766             // Close any open folder                                                                     
2767             closeFolder();                                                                               
2768             // Open the requested folder                                                                 
2769             openFolder(folderIcon);                                                                      
2770         } else {                                                                                         
2771             // Find the open folder...                                                                   
2772             int folderScreen;                                                                            
2773             if (openFolder != null) {                                                                    
2774                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2775                 // .. and close it                                                                       
2776                 closeFolder(openFolder);                                                                 
2777                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2778                     // Close any folder open on the current screen                                       
2779                     closeFolder();                                                                       
2780                     // Pull the folder onto this screen                                                  
2781                     openFolder(folderIcon);                                                              
2782                 }                                                                                        
2783             }                                                                                            
2784         }                                                                                                
2785                                                                                                          
2786         if (mLauncherCallbacks != null) {                                                                
2787             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2788         }                                                                                                
2789     }                                                                                                    
2790                                                                                                          
2791     /**                                                                                                  
2792      * Event handler for the (Add) Widgets button that appears after a long press                        
2793      * on the home screen.                                                                               
2794      */                                                                                                  
2795     protected void onClickAddWidgetButton(View view) {                                                   
2796         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2797         if (mIsSafeModeEnabled) {                                                                        
2798             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2799         } else {                                                                                         
2800             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2801             if (mLauncherCallbacks != null) {                                                            
2802                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2803             }                                                                                            
2804         }                                                                                                
2805     }                                                                                                    
2806                                                                                                          
2807     /**                                                                                                  
2808      * Event handler for the wallpaper picker button that appears after a long press                     
2809      * on the home screen.                                                                               
2810      */                                                                                                  
2811     protected void onClickWallpaperPicker(View v) {                                                      
2812         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2813         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),     
2814                 REQUEST_PICK_WALLPAPER);                                                                 
2815                                                                                                          
2816         if (mLauncherCallbacks != null) {                                                                
2817             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2818         }                                                                                                
2819     }                                                                                                    
2820                                                                                                          
2821     /**                                                                                                  
2822      * Event handler for a click on the settings button that appears after a long press                  
2823      * on the home screen.                                                                               
2824      */                                                                                                  
2825     protected void onClickSettingsButton(View v) {                                                       
2826         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2827         if (mLauncherCallbacks != null) {                                                                
2828             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2829         }                                                                                                
2830     }                                                                                                    
2831                                                                                                          
2832     public void onTouchDownAllAppsButton(View v) {                                                       
2833         // Provide the same haptic feedback that the system offers for virtual keys.                     
2834         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2835     }                                                                                                    
2836                                                                                                          
2837     public void performHapticFeedbackOnTouchDown(View v) {                                               
2838         // Provide the same haptic feedback that the system offers for virtual keys.                     
2839         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2840     }                                                                                                    
2841                                                                                                          
2842     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2843         if (mHapticFeedbackTouchListener == null) {                                                      
2844             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2845                 @SuppressLint("ClickableViewAccessibility")                                              
2846                 @Override                                                                                
2847                 public boolean onTouch(View v, MotionEvent event) {                                      
2848                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2849                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2850                     }                                                                                    
2851                     return false;                                                                        
2852                 }                                                                                        
2853             };                                                                                           
2854         }                                                                                                
2855         return mHapticFeedbackTouchListener;                                                             
2856     }                                                                                                    
2857                                                                                                          
2858     public void onDragStarted(View view) {                                                               
2859         if (isOnCustomContent()) {                                                                       
2860             // Custom content screen doesn't participate in drag and drop. If on custom                  
2861             // content screen, move to default.                                                          
2862             moveWorkspaceToDefaultScreen();                                                              
2863         }                                                                                                
2864                                                                                                          
2865         if (mLauncherCallbacks != null) {                                                                
2866             mLauncherCallbacks.onDragStarted(view);                                                      
2867         }                                                                                                
2868     }                                                                                                    
2869                                                                                                          
2870     /**                                                                                                  
2871      * Called when the user stops interacting with the launcher.                                         
2872      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2873      */                                                                                                  
2874     protected void onInteractionEnd() {                                                                  
2875         if (mLauncherCallbacks != null) {                                                                
2876             mLauncherCallbacks.onInteractionEnd();                                                       
2877         }                                                                                                
2878     }                                                                                                    
2879                                                                                                          
2880     /**                                                                                                  
2881      * Called when the user starts interacting with the launcher.                                        
2882      * The possible interactions are:                                                                    
2883      *  - open all apps                                                                                  
2884      *  - reorder an app shortcut, or a widget                                                           
2885      *  - open the overview mode.                                                                        
2886      * This is a good time to stop doing things that only make sense                                     
2887      * when the user is on the homescreen and not doing housekeeping.                                    
2888      */                                                                                                  
2889     protected void onInteractionBegin() {                                                                
2890         if (mLauncherCallbacks != null) {                                                                
2891             mLauncherCallbacks.onInteractionBegin();                                                     
2892         }                                                                                                
2893     }                                                                                                    
2894                                                                                                          
2895     /** Updates the interaction state. */                                                                
2896     public void updateInteraction(Workspace.State fromState, Workspace.State toState) {                  
2897         // Only update the interacting state if we are transitioning to/from a view with an              
2898         // overlay                                                                                       
2899         boolean fromStateWithOverlay;                                                                    
2900         boolean toStateWithOverlay;                                                                      
2901         if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
2902             fromStateWithOverlay = fromState != Workspace.State.NORMAL;                                  
2903             toStateWithOverlay = toState != Workspace.State.NORMAL;                                      
2904         } else {                                                                                         
2905             fromStateWithOverlay = fromState != Workspace.State.NORMAL &&                                
2906                     fromState != Workspace.State.NORMAL_HIDDEN;                                          
2907             toStateWithOverlay = toState != Workspace.State.NORMAL &&                                    
2908                     toState != Workspace.State.NORMAL_HIDDEN;                                            
2909         }                                                                                                
2910         if (toStateWithOverlay) {                                                                        
2911             onInteractionBegin();                                                                        
2912         } else if (fromStateWithOverlay) {                                                               
2913             onInteractionEnd();                                                                          
2914         }                                                                                                
2915     }                                                                                                    
2916                                                                                                          
2917     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2918         try {                                                                                            
2919             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2920             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2921         } catch (SecurityException e) {                                                                  
2922             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2923             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2924         } catch (ActivityNotFoundException e) {                                                          
2925             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2926             Log.e(TAG, "Unable to launch settings");                                                     
2927         }                                                                                                
2928     }                                                                                                    
2929                                                                                                          
2930     // returns true if the activity was started                                                          
2931     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2932             UserHandleCompat user) {                                                                     
2933         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2934             // System applications cannot be installed. For now, show a toast explaining that.           
2935             // We may give them the option of disabling apps this way.                                   
2936             int messageId = R.string.uninstall_system_app_text;                                          
2937             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2938             return false;                                                                                
2939         } else {                                                                                         
2940             String packageName = componentName.getPackageName();                                         
2941             String className = componentName.getClassName();                                             
2942             Intent intent = new Intent(                                                                  
2943                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2944             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2945                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2946             if (user != null) {                                                                          
2947                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2948             }                                                                                            
2949             startActivity(intent);                                                                       
2950             return true;                                                                                 
2951         }                                                                                                
2952     }                                                                                                    
2953                                                                                                          
2954     boolean startActivity(View v, Intent intent, Object tag) {                                           
2955         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2956         try {                                                                                            
2957             // Only launch using the new animation if the shortcut has not opted out (this is a          
2958             // private contract between launcher and may be ignored in the future).                      
2959             boolean useLaunchAnimation = (v != null) &&                                                  
2960                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2961             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2962             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2963                                                                                                          
2964             UserHandleCompat user = null;                                                                
2965             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2966                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2967                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2968             }                                                                                            
2969                                                                                                          
2970             Bundle optsBundle = null;                                                                    
2971 <<<<<<< MINE                                                                                             
2972             if (useLaunchAnimation) {                                                                    
2973                 ActivityOptions opts = null;                                                             
2974                 if (sClipRevealMethod != null) {                                                         
2975                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2976                     int left = 0, top = 0;                                                               
2977                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2978                     if (v instanceof TextView) {                                                         
2979                         // Launch from center of icon, not entire view                                   
2980                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2981                         if (icon != null) {                                                              
2982                             Rect bounds = icon.getBounds();                                              
2983                             left = (width - bounds.width()) / 2;                                         
2984                             top = v.getPaddingTop();                                                     
2985                             width = bounds.width();                                                      
2986                             height = bounds.height();                                                    
2987                         }                                                                                
2988                     }                                                                                    
2989                     try {                                                                                
2990                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2991                                 left, top, width, height);                                               
2992                     } catch (IllegalAccessException e) {                                                 
2993                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2994                         sClipRevealMethod = null;                                                        
2995                     } catch (InvocationTargetException e) {                                              
2996                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2997                         sClipRevealMethod = null;                                                        
2998                     }                                                                                    
2999                 }                                                                                        
3000                 if (opts == null && !Utilities.isLmpOrAbove()) {                                         
3001                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                 
3002                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
3003                 }                                                                                        
3004                 optsBundle = opts != null ? opts.toBundle() : null;                                      
3005 ||||||| BASE                                                                                             
3006             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
3007                 // On pre-L devices, we use the scale up transition.                                     
3008                 // Otherwise we use system default.                                                      
3009                 ActivityOptions opts =                                                                   
3010                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3011                 optsBundle = opts.toBundle();                                                            
3012             }                                                                                            
3013                                                                                                          
3014             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3015                 // Could be launching some bookkeeping activity                                          
3016                 startActivity(intent, optsBundle);                                                       
3017             } else {                                                                                     
3018                 // TODO Component can be null when shortcuts are supported for secondary user            
3019                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3020                         intent.getSourceBounds(), optsBundle);                                           
3021             }                                                                                            
3022             return true;                                                                                 
3023         } catch (SecurityException e) {                                                                  
3024             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3025             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3026                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3027                     "or use the exported attribute for this activity. "                                  
3028                     + "tag="+ tag + " intent=" + intent, e);                                             
3029         }                                                                                                
3030         return false;                                                                                    
3031     }                                                                                                    
3032 =======                                                                                                  
3033             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
3034                 // On pre-L devices, we use the scale up transition.                                     
3035                 ActivityOptions opts =                                                                   
3036                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3037                 optsBundle = opts.toBundle();                                                            
3038             } else if (useLaunchAnimation && Utilities.isLmpMr1()) {                                     
3039                 // On L-MR1 devices, we use custom slide up animation without a delay                    
3040                 // On L devices, we use the system default slide up.                                     
3041                 ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,                         
3042                         R.anim.task_open_enter, R.anim.no_anim);                                         
3043                 optsBundle = opts.toBundle();                                                            
3044 >>>>>>> YOURS                                                                                            
3045             }                                                                                            
3046                                                                                                          
3047             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3048                 // Could be launching some bookkeeping activity                                          
3049                 startActivity(intent, optsBundle);                                                       
3050             } else {                                                                                     
3051                 // TODO Component can be null when shortcuts are supported for secondary user            
3052                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3053                         intent.getSourceBounds(), optsBundle);                                           
3054             }                                                                                            
3055             return true;                                                                                 
3056         } catch (SecurityException e) {                                                                  
3057             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3058             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3059                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3060                     "or use the exported attribute for this activity. "                                  
3061                     + "tag="+ tag + " intent=" + intent, e);                                             
3062         }                                                                                                
3063         return false;                                                                                    
3064     }                                                                                                    
3065                                                                                                          
3066     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
3067         boolean success = false;                                                                         
3068         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
3069             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
3070             return false;                                                                                
3071         }                                                                                                
3072         try {                                                                                            
3073             success = startActivity(v, intent, tag);                                                     
3074         } catch (ActivityNotFoundException e) {                                                          
3075             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3076             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
3077         }                                                                                                
3078         return success;                                                                                  
3079     }                                                                                                    
3080                                                                                                          
3081     /**                                                                                                  
3082      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
3083      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
3084      */                                                                                                  
3085     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3086         final int width = fi.getMeasuredWidth();                                                         
3087         final int height = fi.getMeasuredHeight();                                                       
3088                                                                                                          
3089         // Lazy load ImageView, Bitmap and Canvas                                                        
3090         if (mFolderIconImageView == null) {                                                              
3091             mFolderIconImageView = new ImageView(this);                                                  
3092         }                                                                                                
3093         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3094                 mFolderIconBitmap.getHeight() != height) {                                               
3095             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3096             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3097         }                                                                                                
3098                                                                                                          
3099         DragLayer.LayoutParams lp;                                                                       
3100         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3101             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3102         } else {                                                                                         
3103             lp = new DragLayer.LayoutParams(width, height);                                              
3104         }                                                                                                
3105                                                                                                          
3106         // The layout from which the folder is being opened may be scaled, adjust the starting           
3107         // view size by this scale factor.                                                               
3108         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3109         lp.customPosition = true;                                                                        
3110         lp.x = mRectForFolderAnimation.left;                                                             
3111         lp.y = mRectForFolderAnimation.top;                                                              
3112         lp.width = (int) (scale * width);                                                                
3113         lp.height = (int) (scale * height);                                                              
3114                                                                                                          
3115         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3116         fi.draw(mFolderIconCanvas);                                                                      
3117         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3118         if (fi.getFolder() != null) {                                                                    
3119             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3120             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3121         }                                                                                                
3122         // Just in case this image view is still in the drag layer from a previous animation,            
3123         // we remove it and re-add it.                                                                   
3124         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3125             mDragLayer.removeView(mFolderIconImageView);                                                 
3126         }                                                                                                
3127         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3128         if (fi.getFolder() != null) {                                                                    
3129             fi.getFolder().bringToFront();                                                               
3130         }                                                                                                
3131     }                                                                                                    
3132                                                                                                          
3133     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3134         if (fi == null) return;                                                                          
3135         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3136         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3137         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3138                                                                                                          
3139         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3140         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3141             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3142             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3143             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3144         }                                                                                                
3145                                                                                                          
3146         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3147         copyFolderIconToImage(fi);                                                                       
3148         fi.setVisibility(View.INVISIBLE);                                                                
3149                                                                                                          
3150         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3151                 scaleX, scaleY);                                                                         
3152         if (Utilities.isLmpOrAbove()) {                                                                  
3153             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3154         }                                                                                                
3155         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3156         oa.start();                                                                                      
3157     }                                                                                                    
3158                                                                                                          
3159     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3160         if (fi == null) return;                                                                          
3161         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3162         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3163         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3164                                                                                                          
3165         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3166                                                                                                          
3167         // We remove and re-draw the FolderIcon in-case it has changed                                   
3168         mDragLayer.removeView(mFolderIconImageView);                                                     
3169         copyFolderIconToImage(fi);                                                                       
3170         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3171                 scaleX, scaleY);                                                                         
3172         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3173         oa.addListener(new AnimatorListenerAdapter() {                                                   
3174             @Override                                                                                    
3175             public void onAnimationEnd(Animator animation) {                                             
3176                 if (cl != null) {                                                                        
3177                     cl.clearFolderLeaveBehind();                                                         
3178                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3179                     mDragLayer.removeView(mFolderIconImageView);                                         
3180                     fi.setVisibility(View.VISIBLE);                                                      
3181                 }                                                                                        
3182             }                                                                                            
3183         });                                                                                              
3184         oa.start();                                                                                      
3185     }                                                                                                    
3186                                                                                                          
3187     /**                                                                                                  
3188      * Opens the user folder described by the specified tag. The opening of the folder                   
3189      * is animated relative to the specified View. If the View is null, no animation                     
3190      * is played.                                                                                        
3191      *                                                                                                   
3192      * @param folderInfo The FolderInfo describing the folder to open.                                   
3193      */                                                                                                  
3194     public void openFolder(FolderIcon folderIcon) {                                                      
3195         Folder folder = folderIcon.getFolder();                                                          
3196         Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                      
3197         if (openFolder != null && openFolder != folder) {                                                
3198             // Close any open folder before opening a folder.                                            
3199             closeFolder();                                                                               
3200         }                                                                                                
3201                                                                                                          
3202         FolderInfo info = folder.mInfo;                                                                  
3203                                                                                                          
3204         info.opened = true;                                                                              
3205                                                                                                          
3206         // While the folder is open, the position of the icon cannot change.                             
3207         ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                     
3208                                                                                                          
3209         // Just verify that the folder hasn't already been added to the DragLayer.                       
3210         // There was a one-off crash where the folder had a parent already.                              
3211         if (folder.getParent() == null) {                                                                
3212             mDragLayer.addView(folder);                                                                  
3213             mDragController.addDropTarget((DropTarget) folder);                                          
3214         } else {                                                                                         
3215             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3216                     folder.getParent() + ").");                                                          
3217         }                                                                                                
3218         folder.animateOpen();                                                                            
3219         growAndFadeOutFolderIcon(folderIcon);                                                            
3220                                                                                                          
3221         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3222         // the workspace items                                                                           
3223         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3224         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3225     }                                                                                                    
3226                                                                                                          
3227     public void closeFolder() {                                                                          
3228         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3229         if (folder != null) {                                                                            
3230             if (folder.isEditingName()) {                                                                
3231                 folder.dismissEditingName();                                                             
3232             }                                                                                            
3233             closeFolder(folder);                                                                         
3234         }                                                                                                
3235     }                                                                                                    
3236                                                                                                          
3237     public void closeFolder(Folder folder) {                                                             
3238         folder.getInfo().opened = false;                                                                 
3239                                                                                                          
3240         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3241         if (parent != null) {                                                                            
3242             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3243             shrinkAndFadeInFolderIcon(fi);                                                               
3244             if (fi != null) {                                                                            
3245                 ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                      
3246             }                                                                                            
3247         }                                                                                                
3248         folder.animateClosed();                                                                          
3249                                                                                                          
3250         // Notify the accessibility manager that this folder "window" has disappeard and no              
3251         // longer occludeds the workspace items                                                          
3252         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3253     }                                                                                                    
3254                                                                                                          
3255     public boolean onLongClick(View v) {                                                                 
3256         if (!isDraggingEnabled()) return false;                                                          
3257         if (isWorkspaceLocked()) return false;                                                           
3258         if (mState != State.WORKSPACE) return false;                                                     
3259                                                                                                          
3260         if (v instanceof Workspace) {                                                                    
3261             if (!mWorkspace.isInOverviewMode()) {                                                        
3262                 if (!mWorkspace.isTouchActive()) {                                                       
3263                     showOverviewMode(true);                                                              
3264                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3265                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3266                     return true;                                                                         
3267                 } else {                                                                                 
3268                     return false;                                                                        
3269                 }                                                                                        
3270             } else {                                                                                     
3271                 return false;                                                                            
3272             }                                                                                            
3273         }                                                                                                
3274                                                                                                          
3275         CellLayout.CellInfo longClickCellInfo = null;                                                    
3276         View itemUnderLongClick = null;                                                                  
3277         if (v.getTag() instanceof ItemInfo) {                                                            
3278             ItemInfo info = (ItemInfo) v.getTag();                                                       
3279             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3280             itemUnderLongClick = longClickCellInfo.cell;                                                 
3281             resetAddInfo();                                                                              
3282         }                                                                                                
3283                                                                                                          
3284         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3285         // on hotseat items.                                                                             
3286         final boolean inHotseat = isHotseatLayout(v);                                                    
3287         if (!mDragController.isDragging()) {                                                             
3288             if (itemUnderLongClick == null) {                                                            
3289                 // User long pressed on empty space                                                      
3290                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3291                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3292                 if (mWorkspace.isInOverviewMode()) {                                                     
3293                     mWorkspace.startReordering(v);                                                       
3294                 } else {                                                                                 
3295                     showOverviewMode(true);                                                              
3296                 }                                                                                        
3297             } else {                                                                                     
3298                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3299                         mHotseat.getOrderInHotseat(                                                      
3300                                 longClickCellInfo.cellX,                                                 
3301                                 longClickCellInfo.cellY));                                               
3302                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3303                     // User long pressed on an item                                                      
3304                     mWorkspace.startDrag(longClickCellInfo);                                             
3305                 }                                                                                        
3306             }                                                                                            
3307         }                                                                                                
3308         return true;                                                                                     
3309     }                                                                                                    
3310                                                                                                          
3311     boolean isHotseatLayout(View layout) {                                                               
3312         return mHotseat != null && layout != null &&                                                     
3313                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3314     }                                                                                                    
3315                                                                                                          
3316     /**                                                                                                  
3317      * Returns the CellLayout of the specified container at the specified screen.                        
3318      */                                                                                                  
3319     public CellLayout getCellLayout(long container, long screenId) {                                     
3320         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3321             if (mHotseat != null) {                                                                      
3322                 return mHotseat.getLayout();                                                             
3323             } else {                                                                                     
3324                 return null;                                                                             
3325             }                                                                                            
3326         } else {                                                                                         
3327             return mWorkspace.getScreenWithId(screenId);                                                 
3328         }                                                                                                
3329     }                                                                                                    
3330                                                                                                          
3331     /**                                                                                                  
3332      * For overridden classes.                                                                           
3333      */                                                                                                  
3334     public boolean isAllAppsVisible() {                                                                  
3335         return isAppsViewVisible();                                                                      
3336     }                                                                                                    
3337                                                                                                          
3338     public boolean isAppsViewVisible() {                                                                 
3339         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3340     }                                                                                                    
3341                                                                                                          
3342     public boolean isWidgetsViewVisible() {                                                              
3343         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3344     }                                                                                                    
3345                                                                                                          
3346     private void setWorkspaceBackground(int background) {                                                
3347         switch (background) {                                                                            
3348             case WORKSPACE_BACKGROUND_TRANSPARENT:                                                       
3349                 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));                 
3350                 break;                                                                                   
3351             case WORKSPACE_BACKGROUND_BLACK:                                                             
3352                 getWindow().setBackgroundDrawable(null);                                                 
3353                 break;                                                                                   
3354             default:                                                                                     
3355                 getWindow().setBackgroundDrawable(mWorkspaceBackgroundDrawable);                         
3356         }                                                                                                
3357     }                                                                                                    
3358                                                                                                          
3359     protected void changeWallpaperVisiblity(boolean visible) {                                           
3360         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3361         int curflags = getWindow().getAttributes().flags                                                 
3362                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3363         if (wpflags != curflags) {                                                                       
3364             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3365         }                                                                                                
3366         setWorkspaceBackground(visible ? WORKSPACE_BACKGROUND_GRADIENT : WORKSPACE_BACKGROUND_BLACK);    
3367     }                                                                                                    
3368                                                                                                          
3369     @Override                                                                                            
3370     public void onTrimMemory(int level) {                                                                
3371         super.onTrimMemory(level);                                                                       
3372         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3373             // The widget preview db can result in holding onto over                                     
3374             // 3MB of memory for caching which isn't necessary.                                          
3375             SQLiteDatabase.releaseMemory();                                                              
3376                                                                                                          
3377             // This clears all widget bitmaps from the widget tray                                       
3378             // TODO(hyunyoungs)                                                                          
3379         }                                                                                                
3380         if (mLauncherCallbacks != null) {                                                                
3381             mLauncherCallbacks.onTrimMemory(level);                                                      
3382         }                                                                                                
3383     }                                                                                                    
3384                                                                                                          
3385     @Override                                                                                            
3386     public void onStateTransitionHideSearchBar() {                                                       
3387         // Hide the search bar                                                                           
3388         if (mSearchDropTargetBar != null) {                                                              
3389             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3390         }                                                                                                
3391     }                                                                                                    
3392                                                                                                          
3393     public void showWorkspace(boolean animated) {                                                        
3394         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null,          
3395                 true);                                                                                   
3396     }                                                                                                    
3397                                                                                                          
3398     public void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                           
3399         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                
3400                 onCompleteRunnable, true);                                                               
3401     }                                                                                                    
3402                                                                                                          
3403     protected void showWorkspace(int snapToPage, boolean animated) {                                     
3404         showWorkspace(snapToPage, animated, null, true);                                                 
3405     }                                                                                                    
3406                                                                                                          
3407     void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable,                    
3408             boolean notifyLauncherCallbacks) {                                                           
3409         boolean changed = mState != State.WORKSPACE ||                                                   
3410                 mWorkspace.getState() != Workspace.State.NORMAL;                                         
3411         if (changed) {                                                                                   
3412             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3413             mWorkspace.setVisibility(View.VISIBLE);                                                      
3414             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3415                     snapToPage, animated, onCompleteRunnable);                                           
3416                                                                                                          
3417             // Show the search bar (only animate if we were showing the drop target bar in spring        
3418             // loaded mode)                                                                              
3419             if (mSearchDropTargetBar != null) {                                                          
3420                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3421             }                                                                                            
3422                                                                                                          
3423             // Set focus to the AppsCustomize button                                                     
3424             if (mAllAppsButton != null) {                                                                
3425                 mAllAppsButton.requestFocus();                                                           
3426             }                                                                                            
3427         }                                                                                                
3428                                                                                                          
3429         // Change the state *after* we've called all the transition code                                 
3430         mState = State.WORKSPACE;                                                                        
3431                                                                                                          
3432         // Resume the auto-advance of widgets                                                            
3433         mUserPresent = true;                                                                             
3434         updateAutoAdvanceState();                                                                        
3435                                                                                                          
3436         if (changed) {                                                                                   
3437             // Send an accessibility event to announce the context change                                
3438             getWindow().getDecorView()                                                                   
3439                     .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);               
3440             if (notifyLauncherCallbacks) {                                                               
3441                 // Dismiss all apps when the workspace is shown                                          
3442                 if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {       
3443                     mLauncherCallbacks.onAllAppsHidden();                                                
3444                 }                                                                                        
3445             }                                                                                            
3446         }                                                                                                
3447     }                                                                                                    
3448                                                                                                          
3449     void showOverviewMode(boolean animated) {                                                            
3450         mWorkspace.setVisibility(View.VISIBLE);                                                          
3451         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3452                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                      
3453                 null /* onCompleteRunnable */);                                                          
3454         mState = State.WORKSPACE;                                                                        
3455     }                                                                                                    
3456                                                                                                          
3457     /**                                                                                                  
3458      * Shows the apps view.                                                                              
3459      */                                                                                                  
3460     void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps) {           
3461         if (resetListToTop) {                                                                            
3462             mAppsView.scrollToTop();                                                                     
3463         }                                                                                                
3464         if (updatePredictedApps) {                                                                       
3465             tryAndUpdatePredictedApps();                                                                 
3466         }                                                                                                
3467         showAppsOrWidgets(animated, State.APPS);                                                         
3468     }                                                                                                    
3469                                                                                                          
3470     /**                                                                                                  
3471      * Shows the widgets view.                                                                           
3472      */                                                                                                  
3473     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3474         if (LOGD) Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);     
3475         if (resetPageToZero) {                                                                           
3476             mWidgetsView.scrollToTop();                                                                  
3477         }                                                                                                
3478         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3479                                                                                                          
3480         mWidgetsView.post(new Runnable() {                                                               
3481             @Override                                                                                    
3482             public void run() {                                                                          
3483                 mWidgetsView.requestFocus();                                                             
3484             }                                                                                            
3485         });                                                                                              
3486     }                                                                                                    
3487                                                                                                          
3488     /**                                                                                                  
3489      * Sets up the transition to show the apps/widgets view.                                             
3490      *                                                                                                   
3491      * @return whether the current from and to state allowed this operation                              
3492      */                                                                                                  
3493     // TODO: calling method should use the return value so that when {@code false} is returned           
3494     // the workspace transition doesn't fall into invalid state.                                         
3495     private boolean showAppsOrWidgets(boolean animated, State toState) {                                 
3496         if (mState != State.WORKSPACE &&  mState != State.APPS_SPRING_LOADED &&                          
3497                 mState != State.WIDGETS_SPRING_LOADED) {                                                 
3498             return false;                                                                                
3499         }                                                                                                
3500         if (toState != State.APPS && toState != State.WIDGETS) {                                         
3501             return false;                                                                                
3502         }                                                                                                
3503                                                                                                          
3504         if (toState == State.APPS) {                                                                     
3505             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3506             if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {           
3507                 mLauncherCallbacks.onAllAppsShown();                                                     
3508             }                                                                                            
3509         } else {                                                                                         
3510             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3511         }                                                                                                
3512                                                                                                          
3513         // Change the state *after* we've called all the transition code                                 
3514         mState = toState;                                                                                
3515                                                                                                          
3516         // Pause the auto-advance of widgets until we are out of AllApps                                 
3517         mUserPresent = false;                                                                            
3518         updateAutoAdvanceState();                                                                        
3519         closeFolder();                                                                                   
3520                                                                                                          
3521         // Send an accessibility event to announce the context change                                    
3522         getWindow().getDecorView()                                                                       
3523                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3524         return true;                                                                                     
3525     }                                                                                                    
3526                                                                                                          
3527     /**                                                                                                  
3528      * Updates the workspace and interaction state on state change, and return the animation to this     
3529      * new state.                                                                                        
3530      */                                                                                                  
3531     public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, int toPage,              
3532             boolean animated, HashMap<View, Integer> layerViews) {                                       
3533         Workspace.State fromState = mWorkspace.getState();                                               
3534         Animator anim = mWorkspace.setStateWithAnimation(toState, toPage, animated, layerViews);         
3535         updateInteraction(fromState, toState);                                                           
3536         return anim;                                                                                     
3537     }                                                                                                    
3538                                                                                                          
3539     public void enterSpringLoadedDragMode() {                                                            
3540         if (LOGD) Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", mState.name()));      
3541         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3542                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3543             return;                                                                                      
3544         }                                                                                                
3545                                                                                                          
3546         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3547                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true /* animated */,           
3548                 null /* onCompleteRunnable */);                                                          
3549         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3550     }                                                                                                    
3551                                                                                                          
3552     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                 
3553             final Runnable onCompleteRunnable) {                                                         
3554         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3555                                                                                                          
3556         if (successfulDrop) {                                                                            
3557             // We need to trigger all apps hidden to notify search to update itself before the           
3558             // delayed call to showWorkspace below                                                       
3559             if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {           
3560                 mLauncherCallbacks.onAllAppsHidden();                                                    
3561             }                                                                                            
3562         }                                                                                                
3563                                                                                                          
3564         mHandler.postDelayed(new Runnable() {                                                            
3565             @Override                                                                                    
3566             public void run() {                                                                          
3567                 if (successfulDrop) {                                                                    
3568                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3569                     //                                                                                   
3570                     // Before we show workspace, hide all apps again because                             
3571                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3572                     // clean up our state transition functions                                           
3573                     mWidgetsView.setVisibility(View.GONE);                                               
3574                     showWorkspace(true, onCompleteRunnable);                                             
3575                 } else {                                                                                 
3576                     exitSpringLoadedDragMode();                                                          
3577                 }                                                                                        
3578             }                                                                                            
3579         }, delay);                                                                                       
3580     }                                                                                                    
3581                                                                                                          
3582     void exitSpringLoadedDragMode() {                                                                    
3583         if (mState == State.APPS_SPRING_LOADED) {                                                        
3584             showAppsView(true /* animated */, false /* resetListToTop */,                                
3585                     false /* updatePredictedApps */);                                                    
3586         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3587             showWidgetsView(true, false);                                                                
3588         }                                                                                                
3589     }                                                                                                    
3590                                                                                                          
3591     /**                                                                                                  
3592      * Updates the set of predicted apps if it hasn't been updated since the last time Launcher was      
3593      * resumed.                                                                                          
3594      */                                                                                                  
3595     private void tryAndUpdatePredictedApps() {                                                           
3596         if (mLauncherCallbacks != null) {                                                                
3597             List<ComponentName> apps = mLauncherCallbacks.getPredictedApps();                            
3598             if (!apps.isEmpty()) {                                                                       
3599                 mAppsView.setPredictedApps(apps);                                                        
3600             }                                                                                            
3601         }                                                                                                
3602     }                                                                                                    
3603                                                                                                          
3604     void lockAllApps() {                                                                                 
3605         // TODO                                                                                          
3606     }                                                                                                    
3607                                                                                                          
3608     void unlockAllApps() {                                                                               
3609         // TODO                                                                                          
3610     }                                                                                                    
3611                                                                                                          
3612     protected void disableVoiceButtonProxy(boolean disable) {                                            
3613         // NO-OP                                                                                         
3614     }                                                                                                    
3615                                                                                                          
3616     public View getOrCreateQsbBar() {                                                                    
3617         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3618             return mLauncherCallbacks.getQsbBar();                                                       
3619         }                                                                                                
3620                                                                                                          
3621         if (mQsb == null) {                                                                              
3622             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3623             if (searchProvider == null) {                                                                
3624                 return null;                                                                             
3625             }                                                                                            
3626                                                                                                          
3627             Bundle opts = new Bundle();                                                                  
3628             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3629                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3630                                                                                                          
3631             SharedPreferences sp = getSharedPreferences(                                                 
3632                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3633             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3634             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3635             if (!searchProvider.provider.flattenToString().equals(                                       
3636                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3637                     || (widgetInfo == null)                                                              
3638                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3639                 // A valid widget is not already bound.                                                  
3640                 if (widgetId > -1) {                                                                     
3641                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3642                     widgetId = -1;                                                                       
3643                 }                                                                                        
3644                                                                                                          
3645                 // Try to bind a new widget                                                              
3646                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3647                                                                                                          
3648                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3649                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3650                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3651                     widgetId = -1;                                                                       
3652                 }                                                                                        
3653                                                                                                          
3654                 sp.edit()                                                                                
3655                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3656                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3657                     .commit();                                                                           
3658             }                                                                                            
3659                                                                                                          
3660             if (widgetId != -1) {                                                                        
3661                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3662                 mQsb.updateAppWidgetOptions(opts);                                                       
3663                 mQsb.setPadding(0, 0, 0, 0);                                                             
3664                 mSearchDropTargetBar.addView(mQsb);                                                      
3665                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3666             }                                                                                            
3667         }                                                                                                
3668         return mQsb;                                                                                     
3669     }                                                                                                    
3670                                                                                                          
3671     private void reinflateQSBIfNecessary() {                                                             
3672         if (mQsb instanceof LauncherAppWidgetHostView &&                                                 
3673                 ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                              
3674             mSearchDropTargetBar.removeView(mQsb);                                                       
3675             mQsb = null;                                                                                 
3676             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3677         }                                                                                                
3678     }                                                                                                    
3679                                                                                                          
3680     @Override                                                                                            
3681     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3682         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3683         final List<CharSequence> text = event.getText();                                                 
3684         text.clear();                                                                                    
3685         // Populate event with a fake title based on the current state.                                  
3686         if (mState == State.APPS) {                                                                      
3687             text.add(getString(R.string.all_apps_button_label));                                         
3688         } else if (mState == State.WIDGETS) {                                                            
3689             text.add(getString(R.string.widget_button_text));                                            
3690         } else {                                                                                         
3691             text.add(getString(R.string.all_apps_home_button_label));                                    
3692         }                                                                                                
3693         return result;                                                                                   
3694     }                                                                                                    
3695                                                                                                          
3696     /**                                                                                                  
3697      * Receives notifications when system dialogs are to be closed.                                      
3698      */                                                                                                  
3699     @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                            
3700         @Override                                                                                        
3701         public void onReceive(Context context, Intent intent) {                                          
3702             closeSystemDialogs();                                                                        
3703         }                                                                                                
3704     }                                                                                                    
3705                                                                                                          
3706     /**                                                                                                  
3707      * Receives notifications whenever the appwidgets are reset.                                         
3708      */                                                                                                  
3709     private class AppWidgetResetObserver extends ContentObserver {                                       
3710         public AppWidgetResetObserver() {                                                                
3711             super(new Handler());                                                                        
3712         }                                                                                                
3713                                                                                                          
3714         @Override                                                                                        
3715         public void onChange(boolean selfChange) {                                                       
3716             onAppWidgetReset();                                                                          
3717         }                                                                                                
3718     }                                                                                                    
3719                                                                                                          
3720     /**                                                                                                  
3721      * If the activity is currently paused, signal that we need to run the passed Runnable               
3722      * in onResume.                                                                                      
3723      *                                                                                                   
3724      * This needs to be called from incoming places where resources might have been loaded               
3725      * while the activity is paused. That is because the Configuration (e.g., rotation)  might be        
3726      * wrong when we're not running, and if the activity comes back to what the configuration was        
3727      * when we were paused, activity is not restarted.                                                   
3728      *                                                                                                   
3729      * Implementation of the method from LauncherModel.Callbacks.                                        
3730      *                                                                                                   
3731      * @return {@code true} if we are currently paused. The caller might be able to skip some work       
3732      */                                                                                                  
3733     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3734         if (mPaused) {                                                                                   
3735             if (LOGD) Log.d(TAG, "Deferring update until onResume");                                     
3736             if (deletePreviousRunnables) {                                                               
3737                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3738                 }                                                                                        
3739             }                                                                                            
3740             mBindOnResumeCallbacks.add(run);                                                             
3741             return true;                                                                                 
3742         } else {                                                                                         
3743             return false;                                                                                
3744         }                                                                                                
3745     }                                                                                                    
3746                                                                                                          
3747     private boolean waitUntilResume(Runnable run) {                                                      
3748         return waitUntilResume(run, false);                                                              
3749     }                                                                                                    
3750                                                                                                          
3751     public void addOnResumeCallback(Runnable run) {                                                      
3752         mOnResumeCallbacks.add(run);                                                                     
3753     }                                                                                                    
3754                                                                                                          
3755     /**                                                                                                  
3756      * If the activity is currently paused, signal that we need to re-run the loader                     
3757      * in onResume.                                                                                      
3758      *                                                                                                   
3759      * This needs to be called from incoming places where resources might have been loaded               
3760      * while we are paused.  That is becaues the Configuration might be wrong                            
3761      * when we're not running, and if it comes back to what it was when we                               
3762      * were paused, we are not restarted.                                                                
3763      *                                                                                                   
3764      * Implementation of the method from LauncherModel.Callbacks.                                        
3765      *                                                                                                   
3766      * @return true if we are currently paused.  The caller might be able to                             
3767      * skip some work in that case since we will come back again.                                        
3768      */                                                                                                  
3769     public boolean setLoadOnResume() {                                                                   
3770         if (mPaused) {                                                                                   
3771             if (LOGD) Log.d(TAG, "setLoadOnResume");                                                     
3772             mOnResumeNeedsLoad = true;                                                                   
3773             return true;                                                                                 
3774         } else {                                                                                         
3775             return false;                                                                                
3776         }                                                                                                
3777     }                                                                                                    
3778                                                                                                          
3779     /**                                                                                                  
3780      * Implementation of the method from LauncherModel.Callbacks.                                        
3781      */                                                                                                  
3782     public int getCurrentWorkspaceScreen() {                                                             
3783         if (mWorkspace != null) {                                                                        
3784             return mWorkspace.getCurrentPage();                                                          
3785         } else {                                                                                         
3786             return SCREEN_COUNT / 2;                                                                     
3787         }                                                                                                
3788     }                                                                                                    
3789                                                                                                          
3790     /**                                                                                                  
3791      * Refreshes the shortcuts shown on the workspace.                                                   
3792      *                                                                                                   
3793      * Implementation of the method from LauncherModel.Callbacks.                                        
3794      */                                                                                                  
3795     public void startBinding() {                                                                         
3796         setWorkspaceLoading(true);                                                                       
3797                                                                                                          
3798         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3799         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3800         // from scratch again                                                                            
3801         mBindOnResumeCallbacks.clear();                                                                  
3802                                                                                                          
3803         // Clear the workspace because it's going to be rebound                                          
3804         mWorkspace.clearDropTargets();                                                                   
3805         mWorkspace.removeAllWorkspaceScreens();                                                          
3806                                                                                                          
3807         mWidgetsToAdvance.clear();                                                                       
3808         if (mHotseat != null) {                                                                          
3809             mHotseat.resetLayout();                                                                      
3810         }                                                                                                
3811     }                                                                                                    
3812                                                                                                          
3813     @Override                                                                                            
3814     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3815         bindAddScreens(orderedScreenIds);                                                                
3816                                                                                                          
3817         // If there are no screens, we need to have an empty screen                                      
3818         if (orderedScreenIds.size() == 0) {                                                              
3819             mWorkspace.addExtraEmptyScreen();                                                            
3820         }                                                                                                
3821                                                                                                          
3822         // Create the custom content page (this call updates mDefaultScreen which calls                  
3823         // setCurrentPage() so ensure that all pages are added before calling this).                     
3824         if (hasCustomContentToLeft()) {                                                                  
3825             mWorkspace.createCustomContentContainer();                                                   
3826             populateCustomContentContainer();                                                            
3827         }                                                                                                
3828     }                                                                                                    
3829                                                                                                          
3830     @Override                                                                                            
3831     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3832         // Log to disk                                                                                   
3833         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3834         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3835                 TextUtils.join(", ", orderedScreenIds), true);                                           
3836         int count = orderedScreenIds.size();                                                             
3837         for (int i = 0; i < count; i++) {                                                                
3838             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3839         }                                                                                                
3840     }                                                                                                    
3841                                                                                                          
3842     private boolean shouldShowWeightWatcher() {                                                          
3843         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3844         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3845         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3846                                                                                                          
3847         return show;                                                                                     
3848     }                                                                                                    
3849                                                                                                          
3850     private void toggleShowWeightWatcher() {                                                             
3851         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3852         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3853         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3854                                                                                                          
3855         show = !show;                                                                                    
3856                                                                                                          
3857         SharedPreferences.Editor editor = sp.edit();                                                     
3858         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3859         editor.commit();                                                                                 
3860                                                                                                          
3861         if (mWeightWatcher != null) {                                                                    
3862             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3863         }                                                                                                
3864     }                                                                                                    
3865                                                                                                          
3866     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3867                               final ArrayList<ItemInfo> addNotAnimated,                                  
3868                               final ArrayList<ItemInfo> addAnimated,                                     
3869                               final ArrayList<AppInfo> addedApps) {                                      
3870         Runnable r = new Runnable() {                                                                    
3871             public void run() {                                                                          
3872                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3873             }                                                                                            
3874         };                                                                                               
3875         if (waitUntilResume(r)) {                                                                        
3876             return;                                                                                      
3877         }                                                                                                
3878                                                                                                          
3879         // Add the new screens                                                                           
3880         if (newScreens != null) {                                                                        
3881             bindAddScreens(newScreens);                                                                  
3882         }                                                                                                
3883                                                                                                          
3884         // We add the items without animation on non-visible pages, and with                             
3885         // animations on the new page (which we will try and snap to).                                   
3886         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3887             bindItems(addNotAnimated, 0,                                                                 
3888                     addNotAnimated.size(), false);                                                       
3889         }                                                                                                
3890         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3891             bindItems(addAnimated, 0,                                                                    
3892                     addAnimated.size(), true);                                                           
3893         }                                                                                                
3894                                                                                                          
3895         // Remove the extra empty screen                                                                 
3896         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3897                                                                                                          
3898         if (addedApps != null && mAppsView != null) {                                                    
3899             mAppsView.addApps(addedApps);                                                                
3900         }                                                                                                
3901     }                                                                                                    
3902                                                                                                          
3903     /**                                                                                                  
3904      * Bind the items start-end from the list.                                                           
3905      *                                                                                                   
3906      * Implementation of the method from LauncherModel.Callbacks.                                        
3907      */                                                                                                  
3908     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3909                           final boolean forceAnimateIcons) {                                             
3910         Runnable r = new Runnable() {                                                                    
3911             public void run() {                                                                          
3912                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3913             }                                                                                            
3914         };                                                                                               
3915         if (waitUntilResume(r)) {                                                                        
3916             return;                                                                                      
3917         }                                                                                                
3918                                                                                                          
3919         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3920         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3921         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3922         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3923         Workspace workspace = mWorkspace;                                                                
3924         long newShortcutsScreenId = -1;                                                                  
3925         for (int i = start; i < end; i++) {                                                              
3926             final ItemInfo item = shortcuts.get(i);                                                      
3927                                                                                                          
3928             // Short circuit if we are loading dock items for a configuration which has no dock          
3929             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3930                     mHotseat == null) {                                                                  
3931                 continue;                                                                                
3932             }                                                                                            
3933                                                                                                          
3934             switch (item.itemType) {                                                                     
3935                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3936                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3937                     ShortcutInfo info = (ShortcutInfo) item;                                             
3938                     View shortcut = createShortcut(info);                                                
3939                                                                                                          
3940                     /*                                                                                   
3941                      * TODO: FIX collision case                                                          
3942                      */                                                                                  
3943                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3944                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3945                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3946                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3947                             Object tag = v.getTag();                                                     
3948                             String desc = "Collision while binding workspace item: " + item              
3949                                     + ". Collides with " + tag;                                          
3950                             if (LauncherAppState.isDogfoodBuild()) {                                     
3951                                 throw (new RuntimeException(desc));                                      
3952                             } else {                                                                     
3953                                 Log.d(TAG, desc);                                                        
3954                             }                                                                            
3955                         }                                                                                
3956                     }                                                                                    
3957                                                                                                          
3958                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3959                             item.cellY, 1, 1);                                                           
3960                     if (animateIcons) {                                                                  
3961                         // Animate all the applications up now                                           
3962                         shortcut.setAlpha(0f);                                                           
3963                         shortcut.setScaleX(0f);                                                          
3964                         shortcut.setScaleY(0f);                                                          
3965                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3966                         newShortcutsScreenId = item.screenId;                                            
3967                     }                                                                                    
3968                     break;                                                                               
3969                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3970                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3971                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3972                             (FolderInfo) item, mIconCache);                                              
3973                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3974                             item.cellY, 1, 1);                                                           
3975                     break;                                                                               
3976                 default:                                                                                 
3977                     throw new RuntimeException("Invalid Item Type");                                     
3978             }                                                                                            
3979         }                                                                                                
3980                                                                                                          
3981         if (animateIcons) {                                                                              
3982             // Animate to the correct page                                                               
3983             if (newShortcutsScreenId > -1) {                                                             
3984                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3985                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3986                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3987                     public void run() {                                                                  
3988                         anim.playTogether(bounceAnims);                                                  
3989                         anim.start();                                                                    
3990                     }                                                                                    
3991                 };                                                                                       
3992                 if (newShortcutsScreenId != currentScreenId) {                                           
3993                     // We post the animation slightly delayed to prevent slowdowns                       
3994                     // when we are loading right after we return to launcher.                            
3995                     mWorkspace.postDelayed(new Runnable() {                                              
3996                         public void run() {                                                              
3997                             if (mWorkspace != null) {                                                    
3998                                 mWorkspace.snapToPage(newScreenIndex);                                   
3999                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4000                                         NEW_APPS_ANIMATION_DELAY);                                       
4001                             }                                                                            
4002                         }                                                                                
4003                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4004                 } else {                                                                                 
4005                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4006                 }                                                                                        
4007             }                                                                                            
4008         }                                                                                                
4009         workspace.requestLayout();                                                                       
4010     }                                                                                                    
4011                                                                                                          
4012     /**                                                                                                  
4013      * Implementation of the method from LauncherModel.Callbacks.                                        
4014      */                                                                                                  
4015     public void bindFolders(final LongArrayMap<FolderInfo> folders) {                                    
4016         Runnable r = new Runnable() {                                                                    
4017             public void run() {                                                                          
4018                 bindFolders(folders);                                                                    
4019             }                                                                                            
4020         };                                                                                               
4021         if (waitUntilResume(r)) {                                                                        
4022             return;                                                                                      
4023         }                                                                                                
4024         sFolders = folders.clone();                                                                      
4025     }                                                                                                    
4026                                                                                                          
4027     /**                                                                                                  
4028      * Add the views for a widget to the workspace.                                                      
4029      *                                                                                                   
4030      * Implementation of the method from LauncherModel.Callbacks.                                        
4031      */                                                                                                  
4032     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4033         Runnable r = new Runnable() {                                                                    
4034             public void run() {                                                                          
4035                 bindAppWidget(item);                                                                     
4036             }                                                                                            
4037         };                                                                                               
4038         if (waitUntilResume(r)) {                                                                        
4039             return;                                                                                      
4040         }                                                                                                
4041                                                                                                          
4042         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4043         if (DEBUG_WIDGETS) {                                                                             
4044             Log.d(TAG, "bindAppWidget: " + item);                                                        
4045         }                                                                                                
4046         final Workspace workspace = mWorkspace;                                                          
4047                                                                                                          
4048         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
4049                 LauncherModel.getProviderInfo(this, item.providerName, item.user);                       
4050                                                                                                          
4051         if (!mIsSafeModeEnabled                                                                          
4052                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
4053                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
4054             if (appWidgetInfo == null) {                                                                 
4055                 if (DEBUG_WIDGETS) {                                                                     
4056                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4057                             + " belongs to component " + item.providerName                               
4058                             + ", as the povider is null");                                               
4059                 }                                                                                        
4060                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4061                 return;                                                                                  
4062             }                                                                                            
4063             // Note: This assumes that the id remap broadcast is received before this step.              
4064             // If that is not the case, the id remap will be ignored and user may see the                
4065             // click to setup view.                                                                      
4066             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);      
4067             pendingInfo.spanX = item.spanX;                                                              
4068             pendingInfo.spanY = item.spanY;                                                              
4069             pendingInfo.minSpanX = item.minSpanX;                                                        
4070             pendingInfo.minSpanY = item.minSpanY;                                                        
4071             Bundle options = null;                                                                       
4072                     WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);                  
4073                                                                                                          
4074             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4075             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4076                     newWidgetId, appWidgetInfo, options);                                                
4077                                                                                                          
4078             // TODO consider showing a permission dialog when the widget is clicked.                     
4079             if (!success) {                                                                              
4080                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4081                 if (DEBUG_WIDGETS) {                                                                     
4082                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4083                             + " belongs to component " + item.providerName                               
4084                             + ", as the launcher is unable to bing a new widget id");                    
4085                 }                                                                                        
4086                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4087                 return;                                                                                  
4088             }                                                                                            
4089                                                                                                          
4090             item.appWidgetId = newWidgetId;                                                              
4091                                                                                                          
4092             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4093             // the widget is ready to go.                                                                
4094             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4095                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4096                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4097                                                                                                          
4098             LauncherModel.updateItemInDatabase(this, item);                                              
4099         }                                                                                                
4100                                                                                                          
4101         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
4102             final int appWidgetId = item.appWidgetId;                                                    
4103             if (DEBUG_WIDGETS) {                                                                         
4104                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
4105                         + appWidgetInfo.provider);                                                       
4106             }                                                                                            
4107                                                                                                          
4108             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4109         } else {                                                                                         
4110             appWidgetInfo = null;                                                                        
4111             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
4112                     mIsSafeModeEnabled);                                                                 
4113             view.updateIcon(mIconCache);                                                                 
4114             item.hostView = view;                                                                        
4115             item.hostView.updateAppWidget(null);                                                         
4116             item.hostView.setOnClickListener(this);                                                      
4117         }                                                                                                
4118                                                                                                          
4119         item.hostView.setTag(item);                                                                      
4120         item.onBindAppWidget(this);                                                                      
4121                                                                                                          
4122         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4123                 item.cellY, item.spanX, item.spanY, false);                                              
4124         if (!item.isCustomWidget()) {                                                                    
4125             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
4126         }                                                                                                
4127                                                                                                          
4128         workspace.requestLayout();                                                                       
4129                                                                                                          
4130         if (DEBUG_WIDGETS) {                                                                             
4131             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4132                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4133         }                                                                                                
4134     }                                                                                                    
4135                                                                                                          
4136     /**                                                                                                  
4137      * Restores a pending widget.                                                                        
4138      *                                                                                                   
4139      * @param appWidgetId The app widget id                                                              
4140      * @param cellInfo The position on screen where to create the widget.                                
4141      */                                                                                                  
4142     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4143         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4144         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4145             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4146             return;                                                                                      
4147         }                                                                                                
4148                                                                                                          
4149         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4150         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4151                                                                                                          
4152         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4153         LauncherModel.updateItemInDatabase(this, info);                                                  
4154     }                                                                                                    
4155                                                                                                          
4156     public void onPageBoundSynchronously(int page) {                                                     
4157         mSynchronouslyBoundPages.add(page);                                                              
4158     }                                                                                                    
4159                                                                                                          
4160     /**                                                                                                  
4161      * Callback saying that there aren't any more items to bind.                                         
4162      *                                                                                                   
4163      * Implementation of the method from LauncherModel.Callbacks.                                        
4164      */                                                                                                  
4165     public void finishBindingItems() {                                                                   
4166         Runnable r = new Runnable() {                                                                    
4167             public void run() {                                                                          
4168                 finishBindingItems();                                                                    
4169             }                                                                                            
4170         };                                                                                               
4171         if (waitUntilResume(r)) {                                                                        
4172             return;                                                                                      
4173         }                                                                                                
4174         if (mSavedState != null) {                                                                       
4175             if (!mWorkspace.hasFocus()) {                                                                
4176                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4177             }                                                                                            
4178             mSavedState = null;                                                                          
4179         }                                                                                                
4180                                                                                                          
4181         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4182                                                                                                          
4183         setWorkspaceLoading(false);                                                                      
4184         sendLoadingCompleteBroadcastIfNecessary();                                                       
4185                                                                                                          
4186         // If we received the result of any pending adds while the loader was running (e.g. the          
4187         // widget configuration forced an orientation change), process them now.                         
4188         if (sPendingAddItem != null) {                                                                   
4189             final long screenId = completeAdd(sPendingAddItem);                                          
4190                                                                                                          
4191             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4192             // the screen would be guaranteed to exist after bind, and the page would be set through     
4193             // the workspace restore process.                                                            
4194             mWorkspace.post(new Runnable() {                                                             
4195                 @Override                                                                                
4196                 public void run() {                                                                      
4197                     mWorkspace.snapToScreenId(screenId);                                                 
4198                 }                                                                                        
4199             });                                                                                          
4200             sPendingAddItem = null;                                                                      
4201         }                                                                                                
4202                                                                                                          
4203         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
4204                                                                                                          
4205         if (mLauncherCallbacks != null) {                                                                
4206             mLauncherCallbacks.finishBindingItems(false);                                                
4207         }                                                                                                
4208     }                                                                                                    
4209                                                                                                          
4210     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4211         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4212             String permission =                                                                          
4213                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4214             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4215             sendBroadcast(intent, permission);                                                           
4216             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4217             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4218             editor.apply();                                                                              
4219         }                                                                                                
4220     }                                                                                                    
4221                                                                                                          
4222     public boolean isAllAppsButtonRank(int rank) {                                                       
4223         if (mHotseat != null) {                                                                          
4224             return mHotseat.isAllAppsButtonRank(rank);                                                   
4225         }                                                                                                
4226         return false;                                                                                    
4227     }                                                                                                    
4228                                                                                                          
4229     private boolean canRunNewAppsAnimation() {                                                           
4230         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4231         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4232     }                                                                                                    
4233                                                                                                          
4234     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4235         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4236                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4237                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4238                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4239         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4240         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4241         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4242         return bounceAnim;                                                                               
4243     }                                                                                                    
4244                                                                                                          
4245     public boolean useVerticalBarLayout() {                                                              
4246         return mDeviceProfile.isVerticalBarLayout();                                                     
4247     }                                                                                                    
4248                                                                                                          
4249     protected Rect getSearchBarBounds() {                                                                
4250         return mDeviceProfile.getSearchBarBounds(Utilities.isRtl(getResources()));                       
4251     }                                                                                                    
4252                                                                                                          
4253     public void bindSearchablesChanged() {                                                               
4254         if (mSearchDropTargetBar == null) {                                                              
4255             return;                                                                                      
4256         }                                                                                                
4257         if (mQsb != null) {                                                                              
4258             mSearchDropTargetBar.removeView(mQsb);                                                       
4259             mQsb = null;                                                                                 
4260         }                                                                                                
4261         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4262     }                                                                                                    
4263                                                                                                          
4264     /**                                                                                                  
4265      * A runnable that we can dequeue and re-enqueue when all applications are bound (to prevent         
4266      * multiple calls to bind the same list.)                                                            
4267      */                                                                                                  
4268     @Thunk ArrayList<AppInfo> mTmpAppsList;                                                              
4269     private Runnable mBindAllApplicationsRunnable = new Runnable() {                                     
4270         public void run() {                                                                              
4271             bindAllApplications(mTmpAppsList);                                                           
4272             mTmpAppsList = null;                                                                         
4273         }                                                                                                
4274     };                                                                                                   
4275                                                                                                          
4276     /**                                                                                                  
4277      * Add the icons for all apps.                                                                       
4278      *                                                                                                   
4279      * Implementation of the method from LauncherModel.Callbacks.                                        
4280      */                                                                                                  
4281     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4282         if (waitUntilResume(mBindAllApplicationsRunnable, true)) {                                       
4283             mTmpAppsList = apps;                                                                         
4284             return;                                                                                      
4285                 }                                                                                        
4286                                                                                                          
4287         if (mAppsView != null) {                                                                         
4288             mAppsView.setApps(apps);                                                                     
4289         }                                                                                                
4290         if (mLauncherCallbacks != null) {                                                                
4291             mLauncherCallbacks.bindAllApplications(apps);                                                
4292         }                                                                                                
4293     }                                                                                                    
4294                                                                                                          
4295     /**                                                                                                  
4296      * A package was updated.                                                                            
4297      *                                                                                                   
4298      * Implementation of the method from LauncherModel.Callbacks.                                        
4299      */                                                                                                  
4300     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4301         Runnable r = new Runnable() {                                                                    
4302             public void run() {                                                                          
4303                 bindAppsUpdated(apps);                                                                   
4304             }                                                                                            
4305         };                                                                                               
4306         if (waitUntilResume(r)) {                                                                        
4307             return;                                                                                      
4308         }                                                                                                
4309                                                                                                          
4310         if (mAppsView != null) {                                                                         
4311             mAppsView.updateApps(apps);                                                                  
4312         }                                                                                                
4313     }                                                                                                    
4314                                                                                                          
4315     @Override                                                                                            
4316     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4317         Runnable r = new Runnable() {                                                                    
4318             public void run() {                                                                          
4319                 bindWidgetsRestored(widgets);                                                            
4320             }                                                                                            
4321         };                                                                                               
4322         if (waitUntilResume(r)) {                                                                        
4323             return;                                                                                      
4324         }                                                                                                
4325         mWorkspace.widgetsRestored(widgets);                                                             
4326     }                                                                                                    
4327                                                                                                          
4328     /**                                                                                                  
4329      * Some shortcuts were updated in the background.                                                    
4330      *                                                                                                   
4331      * Implementation of the method from LauncherModel.Callbacks.                                        
4332      */                                                                                                  
4333     @Override                                                                                            
4334     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4335             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4336         Runnable r = new Runnable() {                                                                    
4337             public void run() {                                                                          
4338                 bindShortcutsChanged(updated, removed, user);                                            
4339             }                                                                                            
4340         };                                                                                               
4341         if (waitUntilResume(r)) {                                                                        
4342             return;                                                                                      
4343         }                                                                                                
4344                                                                                                          
4345         if (!updated.isEmpty()) {                                                                        
4346             mWorkspace.updateShortcuts(updated);                                                         
4347         }                                                                                                
4348                                                                                                          
4349         if (!removed.isEmpty()) {                                                                        
4350             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4351             for (ShortcutInfo si : removed) {                                                            
4352                 removedComponents.add(si.getTargetComponent());                                          
4353             }                                                                                            
4354             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4355             // Notify the drag controller                                                                
4356             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4357         }                                                                                                
4358     }                                                                                                    
4359                                                                                                          
4360     /**                                                                                                  
4361      * Update the state of a package, typically related to install state.                                
4362      *                                                                                                   
4363      * Implementation of the method from LauncherModel.Callbacks.                                        
4364      */                                                                                                  
4365     @Override                                                                                            
4366     public void bindRestoreItemsChange(final HashSet<ItemInfo> updates) {                                
4367         Runnable r = new Runnable() {                                                                    
4368             public void run() {                                                                          
4369                 bindRestoreItemsChange(updates);                                                         
4370             }                                                                                            
4371         };                                                                                               
4372         if (waitUntilResume(r)) {                                                                        
4373             return;                                                                                      
4374         }                                                                                                
4375                                                                                                          
4376         mWorkspace.updateRestoreItems(updates);                                                          
4377     }                                                                                                    
4378                                                                                                          
4379     /**                                                                                                  
4380      * A package was uninstalled.  We take both the super set of packageNames                            
4381      * in addition to specific applications to remove, the reason being that                             
4382      * this can be called when a package is updated as well.  In that scenario,                          
4383      * we only remove specific components from the workspace, where as                                   
4384      * package-removal should clear all items by package name.                                           
4385      *                                                                                                   
4386      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4387      * Implementation of the method from LauncherModel.Callbacks.                                        
4388      */                                                                                                  
4389     @Override                                                                                            
4390     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4391             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4392         Runnable r = new Runnable() {                                                                    
4393             public void run() {                                                                          
4394                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4395             }                                                                                            
4396         };                                                                                               
4397         if (waitUntilResume(r)) {                                                                        
4398             return;                                                                                      
4399         }                                                                                                
4400                                                                                                          
4401         if (reason == 0) {                                                                               
4402             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4403             for (AppInfo info : appInfos) {                                                              
4404                 removedComponents.add(info.componentName);                                               
4405             }                                                                                            
4406             if (!packageNames.isEmpty()) {                                                               
4407                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4408             }                                                                                            
4409             if (!removedComponents.isEmpty()) {                                                          
4410                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4411             }                                                                                            
4412             // Notify the drag controller                                                                
4413             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4414                                                                                                          
4415         } else {                                                                                         
4416             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4417         }                                                                                                
4418                                                                                                          
4419         // Update AllApps                                                                                
4420         if (mAppsView != null) {                                                                         
4421             mAppsView.removeApps(appInfos);                                                              
4422         }                                                                                                
4423     }                                                                                                    
4424                                                                                                          
4425     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4426             public void run() {                                                                          
4427                 bindAllPackages(mWidgetsModel);                                                          
4428             }                                                                                            
4429         };                                                                                               
4430                                                                                                          
4431     @Override                                                                                            
4432     public void bindAllPackages(final WidgetsModel model) {                                              
4433         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4434             mWidgetsModel = model;                                                                       
4435             return;                                                                                      
4436         }                                                                                                
4437                                                                                                          
4438         if (mWidgetsView != null && model != null) {                                                     
4439             mWidgetsView.addWidgets(model);                                                              
4440             mWidgetsModel = null;                                                                        
4441         }                                                                                                
4442     }                                                                                                    
4443                                                                                                          
4444     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4445         final Display d = getWindowManager().getDefaultDisplay();                                        
4446         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4447         switch (d.getRotation()) {                                                                       
4448         case Surface.ROTATION_0:                                                                         
4449         case Surface.ROTATION_180:                                                                       
4450             // We are currently in the same basic orientation as the natural orientation                 
4451             naturalOri = configOri;                                                                      
4452             break;                                                                                       
4453         case Surface.ROTATION_90:                                                                        
4454         case Surface.ROTATION_270:                                                                       
4455             // We are currently in the other basic orientation to the natural orientation                
4456             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4457                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4458             break;                                                                                       
4459         }                                                                                                
4460                                                                                                          
4461         int[] oriMap = {                                                                                 
4462                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4463                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4464                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4465                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4466         };                                                                                               
4467         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4468         // is landscape.                                                                                 
4469         int indexOffset = 0;                                                                             
4470         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4471             indexOffset = 1;                                                                             
4472         }                                                                                                
4473         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4474     }                                                                                                    
4475                                                                                                          
4476     public void lockScreenOrientation() {                                                                
4477         if (Utilities.isRotationEnabled(this)) {                                                         
4478             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4479                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4480                         .getConfiguration().orientation));                                               
4481             } else {                                                                                     
4482                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4483             }                                                                                            
4484         }                                                                                                
4485     }                                                                                                    
4486     public void unlockScreenOrientation(boolean immediate) {                                             
4487         if (Utilities.isRotationEnabled(this)) {                                                         
4488             if (immediate) {                                                                             
4489                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4490             } else {                                                                                     
4491                 mHandler.postDelayed(new Runnable() {                                                    
4492                     public void run() {                                                                  
4493                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4494                     }                                                                                    
4495                 }, mRestoreScreenOrientationDelay);                                                      
4496             }                                                                                            
4497         }                                                                                                
4498     }                                                                                                    
4499                                                                                                          
4500     protected boolean isLauncherPreinstalled() {                                                         
4501         if (mLauncherCallbacks != null) {                                                                
4502             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4503         }                                                                                                
4504         PackageManager pm = getPackageManager();                                                         
4505         try {                                                                                            
4506             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4507             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4508                 return true;                                                                             
4509             } else {                                                                                     
4510                 return false;                                                                            
4511             }                                                                                            
4512         } catch (NameNotFoundException e) {                                                              
4513             e.printStackTrace();                                                                         
4514             return false;                                                                                
4515         }                                                                                                
4516     }                                                                                                    
4517                                                                                                          
4518     /**                                                                                                  
4519      * This method indicates whether or not we should suggest default wallpaper dimensions               
4520      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4521      */                                                                                                  
4522     protected boolean overrideWallpaperDimensions() {                                                    
4523         if (mLauncherCallbacks != null) {                                                                
4524             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4525         }                                                                                                
4526         return true;                                                                                     
4527     }                                                                                                    
4528                                                                                                          
4529     /**                                                                                                  
4530      * To be overridden by subclasses to indicate that there is an activity to launch                    
4531      * before showing the standard launcher experience.                                                  
4532      */                                                                                                  
4533     protected boolean hasFirstRunActivity() {                                                            
4534         if (mLauncherCallbacks != null) {                                                                
4535             return mLauncherCallbacks.hasFirstRunActivity();                                             
4536         }                                                                                                
4537         return false;                                                                                    
4538     }                                                                                                    
4539                                                                                                          
4540     /**                                                                                                  
4541      * To be overridden by subclasses to launch any first run activity                                   
4542      */                                                                                                  
4543     protected Intent getFirstRunActivity() {                                                             
4544         if (mLauncherCallbacks != null) {                                                                
4545             return mLauncherCallbacks.getFirstRunActivity();                                             
4546         }                                                                                                
4547         return null;                                                                                     
4548     }                                                                                                    
4549                                                                                                          
4550     /**                                                                                                  
4551      * Returns whether the launcher callbacks overrides search in all apps.                              
4552      */                                                                                                  
4553     @Thunk boolean isAllAppsSearchOverridden() {                                                         
4554         if (DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                       
4555             return false;                                                                                
4556         }                                                                                                
4557                                                                                                          
4558         if (mLauncherCallbacks != null) {                                                                
4559             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4560         }                                                                                                
4561         return false;                                                                                    
4562     }                                                                                                    
4563                                                                                                          
4564     private boolean shouldRunFirstRunActivity() {                                                        
4565         return !ActivityManager.isRunningInTestHarness() &&                                              
4566                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4567     }                                                                                                    
4568                                                                                                          
4569     protected boolean hasRunFirstRunActivity() {                                                         
4570         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4571     }                                                                                                    
4572                                                                                                          
4573     public boolean showFirstRunActivity() {                                                              
4574         if (shouldRunFirstRunActivity() &&                                                               
4575                 hasFirstRunActivity()) {                                                                 
4576             Intent firstRunIntent = getFirstRunActivity();                                               
4577             if (firstRunIntent != null) {                                                                
4578                 startActivity(firstRunIntent);                                                           
4579                 markFirstRunActivityShown();                                                             
4580                 return true;                                                                             
4581             }                                                                                            
4582         }                                                                                                
4583         return false;                                                                                    
4584     }                                                                                                    
4585                                                                                                          
4586     private void markFirstRunActivityShown() {                                                           
4587         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4588         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4589         editor.apply();                                                                                  
4590     }                                                                                                    
4591                                                                                                          
4592     /**                                                                                                  
4593      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4594      * screen that must be displayed and dismissed.                                                      
4595      */                                                                                                  
4596     protected boolean hasDismissableIntroScreen() {                                                      
4597         if (mLauncherCallbacks != null) {                                                                
4598             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4599         }                                                                                                
4600         return false;                                                                                    
4601     }                                                                                                    
4602                                                                                                          
4603     /**                                                                                                  
4604      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4605      */                                                                                                  
4606     protected View getIntroScreen() {                                                                    
4607         if (mLauncherCallbacks != null) {                                                                
4608             return mLauncherCallbacks.getIntroScreen();                                                  
4609         }                                                                                                
4610         return null;                                                                                     
4611     }                                                                                                    
4612                                                                                                          
4613     /**                                                                                                  
4614      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4615      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4616      */                                                                                                  
4617     private boolean shouldShowIntroScreen() {                                                            
4618         return hasDismissableIntroScreen() &&                                                            
4619                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4620     }                                                                                                    
4621                                                                                                          
4622     protected void showIntroScreen() {                                                                   
4623         View introScreen = getIntroScreen();                                                             
4624         changeWallpaperVisiblity(false);                                                                 
4625         if (introScreen != null) {                                                                       
4626             mDragLayer.showOverlayView(introScreen);                                                     
4627         }                                                                                                
4628         if (mLauncherOverlayContainer != null) {                                                         
4629             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4630         }                                                                                                
4631     }                                                                                                    
4632                                                                                                          
4633     public void dismissIntroScreen() {                                                                   
4634         markIntroScreenDismissed();                                                                      
4635         if (showFirstRunActivity()) {                                                                    
4636             // We delay hiding the intro view until the first run activity is showing. This              
4637             // avoids a blip.                                                                            
4638             mWorkspace.postDelayed(new Runnable() {                                                      
4639                 @Override                                                                                
4640                 public void run() {                                                                      
4641                     mDragLayer.dismissOverlayView();                                                     
4642                     if (mLauncherOverlayContainer != null) {                                             
4643                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4644                     }                                                                                    
4645                     showFirstRunClings();                                                                
4646                 }                                                                                        
4647             }, ACTIVITY_START_DELAY);                                                                    
4648         } else {                                                                                         
4649             mDragLayer.dismissOverlayView();                                                             
4650             if (mLauncherOverlayContainer != null) {                                                     
4651                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4652             }                                                                                            
4653             showFirstRunClings();                                                                        
4654         }                                                                                                
4655         changeWallpaperVisiblity(true);                                                                  
4656     }                                                                                                    
4657                                                                                                          
4658     private void markIntroScreenDismissed() {                                                            
4659         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4660         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4661         editor.apply();                                                                                  
4662     }                                                                                                    
4663                                                                                                          
4664     @Thunk void showFirstRunClings() {                                                                   
4665         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4666         // on the device, then we always show the first run cling experience (or if there is no          
4667         // launcher2). Otherwise, we prompt the user upon started for migration                          
4668         LauncherClings launcherClings = new LauncherClings(this);                                        
4669         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4670             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4671                 launcherClings.showMigrationCling();                                                     
4672             } else {                                                                                     
4673                 launcherClings.showLongPressCling(true);                                                 
4674             }                                                                                            
4675         }                                                                                                
4676     }                                                                                                    
4677                                                                                                          
4678     void showWorkspaceSearchAndHotseat() {                                                               
4679         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4680         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4681         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4682         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4683     }                                                                                                    
4684                                                                                                          
4685     void hideWorkspaceSearchAndHotseat() {                                                               
4686         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4687         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4688         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4689         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4690     }                                                                                                    
4691                                                                                                          
4692     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4693         // Called from search suggestion, not supported in other profiles.                               
4694         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4695         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4696         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
4697                 myUser);                                                                                 
4698         if (activityInfo == null) {                                                                      
4699             return null;                                                                                 
4700         }                                                                                                
4701         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4702     }                                                                                                    
4703                                                                                                          
4704     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4705             Bitmap icon) {                                                                               
4706         // Called from search suggestion, not supported in other profiles.                               
4707         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4708                 UserHandleCompat.myUserHandle());                                                        
4709     }                                                                                                    
4710                                                                                                          
4711     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4712             Bitmap icon, UserHandleCompat user) {                                                        
4713         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4714         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4715         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4716     }                                                                                                    
4717                                                                                                          
4718     protected void moveWorkspaceToDefaultScreen() {                                                      
4719         mWorkspace.moveToDefaultScreen(false);                                                           
4720     }                                                                                                    
4721                                                                                                          
4722     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4723         dragView.setTag(dragInfo);                                                                       
4724         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4725         mWorkspace.beginExternalDragShared(dragView, source);                                            
4726     }                                                                                                    
4727                                                                                                          
4728     @Override                                                                                            
4729     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4730         if (mLauncherCallbacks != null) {                                                                
4731             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4732         }                                                                                                
4733     }                                                                                                    
4734                                                                                                          
4735     /**                                                                                                  
4736      * Prints out out state for debugging.                                                               
4737      */                                                                                                  
4738     public void dumpState() {                                                                            
4739         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4740         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4741         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4742         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4743         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4744         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4745         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4746         mModel.dumpState();                                                                              
4747         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4748                                                                                                          
4749         Log.d(TAG, "END launcher3 dump state");                                                          
4750     }                                                                                                    
4751                                                                                                          
4752     @Override                                                                                            
4753     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4754         super.dump(prefix, fd, writer, args);                                                            
4755         synchronized (sDumpLogs) {                                                                       
4756             writer.println(" ");                                                                         
4757             writer.println("Debug logs: ");                                                              
4758             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4759                 writer.println("  " + sDumpLogs.get(i));                                                 
4760             }                                                                                            
4761         }                                                                                                
4762         if (mLauncherCallbacks != null) {                                                                
4763             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4764         }                                                                                                
4765     }                                                                                                    
4766                                                                                                          
4767     public static void dumpDebugLogsToConsole() {                                                        
4768         if (DEBUG_DUMP_LOG) {                                                                            
4769             synchronized (sDumpLogs) {                                                                   
4770                 Log.d(TAG, "");                                                                          
4771                 Log.d(TAG, "*********************");                                                     
4772                 Log.d(TAG, "Launcher debug logs: ");                                                     
4773                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4774                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4775                 }                                                                                        
4776                 Log.d(TAG, "*********************");                                                     
4777                 Log.d(TAG, "");                                                                          
4778             }                                                                                            
4779         }                                                                                                
4780     }                                                                                                    
4781                                                                                                          
4782     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4783         addDumpLog(tag, log, null, debugLog);                                                            
4784     }                                                                                                    
4785                                                                                                          
4786     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4787         if (debugLog) {                                                                                  
4788             if (e != null) {                                                                             
4789                 Log.d(tag, log, e);                                                                      
4790             } else {                                                                                     
4791                 Log.d(tag, log);                                                                         
4792             }                                                                                            
4793         }                                                                                                
4794         if (DEBUG_DUMP_LOG) {                                                                            
4795             sDateStamp.setTime(System.currentTimeMillis());                                              
4796             synchronized (sDumpLogs) {                                                                   
4797                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4798                     + (e == null ? "" : (", Exception: " + e)));                                         
4799             }                                                                                            
4800         }                                                                                                
4801     }                                                                                                    
4802                                                                                                          
4803     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4804         return sCustomAppWidgets.get(name);                                                              
4805     }                                                                                                    
4806                                                                                                          
4807     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4808         return sCustomAppWidgets;                                                                        
4809     }                                                                                                    
4810                                                                                                          
4811     public void dumpLogsToLocalData() {                                                                  
4812         if (DEBUG_DUMP_LOG) {                                                                            
4813             new AsyncTask<Void, Void, Void>() {                                                          
4814                 public Void doInBackground(Void ... args) {                                              
4815                     boolean success = false;                                                             
4816                     sDateStamp.setTime(sRunStart);                                                       
4817                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4818                             + sDateStamp.getDay() + "_"                                                  
4819                             + sDateStamp.getHours() + "-"                                                
4820                             + sDateStamp.getMinutes() + "_"                                              
4821                             + sDateStamp.getSeconds() + ".txt";                                          
4822                                                                                                          
4823                     FileOutputStream fos = null;                                                         
4824                     File outFile = null;                                                                 
4825                     try {                                                                                
4826                         outFile = new File(getFilesDir(), FILENAME);                                     
4827                         outFile.createNewFile();                                                         
4828                         fos = new FileOutputStream(outFile);                                             
4829                     } catch (Exception e) {                                                              
4830                         e.printStackTrace();                                                             
4831                     }                                                                                    
4832                     if (fos != null) {                                                                   
4833                         PrintWriter writer = new PrintWriter(fos);                                       
4834                                                                                                          
4835                         writer.println(" ");                                                             
4836                         writer.println("Debug logs: ");                                                  
4837                         synchronized (sDumpLogs) {                                                       
4838                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4839                                 writer.println("  " + sDumpLogs.get(i));                                 
4840                             }                                                                            
4841                         }                                                                                
4842                         writer.close();                                                                  
4843                     }                                                                                    
4844                     try {                                                                                
4845                         if (fos != null) {                                                               
4846                             fos.close();                                                                 
4847                             success = true;                                                              
4848                         }                                                                                
4849                     } catch (IOException e) {                                                            
4850                         e.printStackTrace();                                                             
4851                     }                                                                                    
4852                     return null;                                                                         
4853                 }                                                                                        
4854             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4855         }                                                                                                
4856     }                                                                                                    
4857 }                                                                                                        
4858                                                                                                          
4859 interface DebugIntents {                                                                                 
4860     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
4861     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
4862 }                                                                                                        


























   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16 package com.android.launcher3;                                                                           
  17                                                                                                          
  18 import android.animation.Animator;                                                                       
  19 import android.animation.AnimatorListenerAdapter;                                                        
  20 import android.animation.AnimatorSet;                                                                    
  21 import android.animation.ObjectAnimator;                                                                 
  22 import android.animation.PropertyValuesHolder;                                                           
  23 import android.animation.ValueAnimator;                                                                  
  24 import android.annotation.SuppressLint;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.IntentSender;                                                                     
  44 import android.content.SharedPreferences;                                                                
  45 import android.content.pm.ActivityInfo;                                                                  
  46 import android.content.pm.ApplicationInfo;                                                               
  47 import android.content.pm.PackageManager.NameNotFoundException;                                          
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.res.Configuration;                                                                
  50 import android.database.ContentObserver;                                                                 
  51 import android.database.sqlite.SQLiteDatabase;                                                           
  52 import android.graphics.Bitmap;                                                                          
  53 import android.graphics.Canvas;                                                                          
  54 import android.graphics.Color;                                                                           
  55 import android.graphics.PorterDuff;                                                                      
  56 import android.graphics.Rect;                                                                            
  57 import android.graphics.drawable.ColorDrawable;                                                          
  58 import android.graphics.drawable.Drawable;                                                               
  59 import android.net.Uri;                                                                                  
  60 import android.os.AsyncTask;                                                                             
  61 import android.os.Build;                                                                                 
  62 import android.os.Bundle;                                                                                
  63 import android.os.Environment;                                                                           
  64 import android.os.Handler;                                                                               
  65 import android.os.Message;                                                                               
  66 import android.os.StrictMode;                                                                            
  67 import android.os.SystemClock;                                                                           
  68 import android.text.Selection;                                                                           
  69 import android.text.SpannableStringBuilder;                                                              
  70 import android.text.TextUtils;                                                                           
  71 import android.text.method.TextKeyListener;                                                              
  72 import android.util.Log;                                                                                 
  73 import android.view.Display;                                                                             
  74 import android.view.Gravity;                                                                             
  75 import android.view.HapticFeedbackConstants;                                                             
  76 import android.view.KeyEvent;                                                                            
  77 import android.view.LayoutInflater;                                                                      
  78 import android.view.Menu;                                                                                
  79 import android.view.MotionEvent;                                                                         
  80 import android.view.Surface;                                                                             
  81 import android.view.View.OnClickListener;                                                                
  82 import android.view.View.OnLongClickListener;                                                            
  83 import android.view.View;                                                                                
  84 import android.view.ViewGroup;                                                                           
  85 import android.view.ViewStub;                                                                            
  86 import android.view.ViewTreeObserver;                                                                    
  87 import android.view.Window;                                                                              
  88 import android.view.WindowManager;                                                                       
  89 import android.view.accessibility.AccessibilityEvent;                                                    
  90 import android.view.inputmethod.InputMethodManager;                                                      
  91 import android.widget.Advanceable;                                                                       
  92 import android.widget.FrameLayout;                                                                       
  93 import android.widget.ImageView;                                                                         
  94 import android.widget.TextView;                                                                          
  95 import android.widget.Toast;                                                                             
  96 import com.android.launcher3.DropTarget.DragObject;                                                      
  97 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  98 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;                                
  99 import com.android.launcher3.allapps.AllAppsContainerView;                                               
 100 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 101 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 102 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 103 import com.android.launcher3.compat.UserHandleCompat;                                                    
 104 import com.android.launcher3.compat.UserManagerCompat;                                                   
 105 import com.android.launcher3.model.WidgetsModel;                                                         
 106 import com.android.launcher3.util.LongArrayMap;                                                          
 107 import com.android.launcher3.util.Thunk;                                                                 
 108 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 109 import com.android.launcher3.widget.WidgetHostViewLoader;                                                
 110 import com.android.launcher3.widget.WidgetsContainerView;                                                
 111 import java.io.DataInputStream;                                                                          
 112 import java.io.DataOutputStream;                                                                         
 113 import java.io.File;                                                                                     
 114 import java.io.FileDescriptor;                                                                           
 115 import java.io.FileNotFoundException;                                                                    
 116 import java.io.FileOutputStream;                                                                         
 117 import java.io.IOException;                                                                              
 118 import java.io.PrintWriter;                                                                              
 119 import java.lang.reflect.InvocationTargetException;                                                      
 120 import java.lang.reflect.Method;                                                                         
 121 import java.text.DateFormat;                                                                             
 122 import java.util.ArrayList;                                                                              
 123 import java.util.Collection;                                                                             
 124 import java.util.Date;                                                                                   
 125 import java.util.HashMap;                                                                                
 126 import java.util.HashSet;                                                                                
 127 import java.util.List;                                                                                   
 128 import java.util.concurrent.atomic.AtomicInteger;                                                        
 129                                                                                                          
 130                                                                                                          
 131 interface DebugIntents {                                                                                 
 132     public static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";         
 133                                                                                                          
 134     public static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";       
 135 }                                                                                                        
 136                                                                                                          
 137 /**                                                                                                      
 138  * Default launcher application.                                                                         
 139  */                                                                                                      
 140 public class Launcher extends Activity implements View.OnClickListener , OnLongClickListener , LauncherMo🔵
 141     static final String TAG = "Launcher";                                                                
 142                                                                                                          
 143     static final boolean LOGD = false;                                                                   
 144                                                                                                          
 145     // Temporary flag                                                                                    
 146     // Temporary flag                                                                                    
 147     static final boolean DISABLE_ALL_APPS_SEARCH_INTEGRATION = true;                                     
 148                                                                                                          
 149     static final boolean PROFILE_STARTUP = false;                                                        
 150                                                                                                          
 151     static final boolean DEBUG_WIDGETS = true;                                                           
 152                                                                                                          
 153     static final boolean DEBUG_STRICT_MODE = false;                                                      
 154                                                                                                          
 155     static final boolean DEBUG_RESUME_TIME = false;                                                      
 156                                                                                                          
 157     static final boolean DEBUG_DUMP_LOG = false;                                                         
 158                                                                                                          
 159     // allow DebugIntents to run                                                                         
 160     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 161                                                                                                          
 162     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 163                                                                                                          
 164     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 165                                                                                                          
 166     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 167                                                                                                          
 168     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 169                                                                                                          
 170     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 171                                                                                                          
 172     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 173                                                                                                          
 174     private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;                                          
 175                                                                                                          
 176     private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;                                       
 177                                                                                                          
 178     private static final int WORKSPACE_BACKGROUND_BLACK = 2;                                             
 179                                                                                                          
 180     /**                                                                                                  
 181      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 182      * request codes used internally.                                                                    
 183      */                                                                                                  
 184     protected static final int REQUEST_LAST = 100;                                                       
 185                                                                                                          
 186     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 187                                                                                                          
 188     static final int SCREEN_COUNT = 5;                                                                   
 189                                                                                                          
 190     // To turn on these properties, type                                                                 
 191     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 192     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 193                                                                                                          
 194     // The Intent extra that defines whether to ignore the launch animation                              
 195     // The Intent extra that defines whether to ignore the launch animation                              
 196     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 197             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 198                                                                                                          
 199     // Type: int                                                                                         
 200     // Type: int                                                                                         
 201     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 202                                                                                                          
 203     // Type: int                                                                                         
 204     // Type: int                                                                                         
 205     private static final String RUNTIME_STATE = "launcher.state";                                        
 206                                                                                                          
 207     // Type: int                                                                                         
 208     // Type: int                                                                                         
 209     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 210                                                                                                          
 211     // Type: int                                                                                         
 212     // Type: int                                                                                         
 213     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 214                                                                                                          
 215     // Type: int                                                                                         
 216     // Type: int                                                                                         
 217     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 218                                                                                                          
 219     // Type: int                                                                                         
 220     // Type: int                                                                                         
 221     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 222                                                                                                          
 223     // Type: int                                                                                         
 224     // Type: int                                                                                         
 225     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 226                                                                                                          
 227     // Type: int                                                                                         
 228     // Type: int                                                                                         
 229     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 230                                                                                                          
 231     // Type: parcelable                                                                                  
 232     // Type: parcelable                                                                                  
 233     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 234                                                                                                          
 235     // Type: parcelable                                                                                  
 236     // Type: parcelable                                                                                  
 237     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 238                                                                                                          
 239     // Type: int[]                                                                                       
 240     // Type: int[]                                                                                       
 241     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 242                                                                                                          
 243     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 244                                                                                                          
 245     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 246                                                                                                          
 247     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 248                                                                                                          
 249     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 250             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 251                                                                                                          
 252     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 253                                                                                                          
 254     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 255                                                                                                          
 256     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 257                                                                                                          
 258     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 259                                                                                                          
 260     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 261                                                                                                          
 262     /**                                                                                                  
 263      * The different states that Launcher can be in.                                                     
 264      */                                                                                                  
 265     enum State {                                                                                         
 266                                                                                                          
 267         NONE,                                                                                            
 268         WORKSPACE,                                                                                       
 269         APPS,                                                                                            
 270         APPS_SPRING_LOADED,                                                                              
 271         WIDGETS,                                                                                         
 272         WIDGETS_SPRING_LOADED;}                                                                          
 273                                                                                                          
 274     @Thunk                                                                                               
 275     State mState = State.WORKSPACE;                                                                      
 276                                                                                                          
 277     @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                   
 278                                                                                                          
 279     private boolean mIsSafeModeEnabled;                                                                  
 280                                                                                                          
 281     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 282                                                                                                          
 283     LauncherOverlay mLauncherOverlay;                                                                    
 284                                                                                                          
 285     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 286                                                                                                          
 287     static final int APPWIDGET_HOST_ID = 1024;                                                           
 288                                                                                                          
 289     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 290                                                                                                          
 291     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 292                                                                                                          
 293     private static final int ACTIVITY_START_DELAY = 1000;                                                
 294                                                                                                          
 295     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 296                                                                                                          
 297     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 298                                                                                                          
 299     // How long to wait before the new-shortcut animation automatically pans the workspace               
 300     // How long to wait before the new-shortcut animation automatically pans the workspace               
 301     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 302                                                                                                          
 303     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 304                                                                                                          
 305     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                    
 306                                                                                                          
 307     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 308             = new CloseSystemDialogsIntentReceiver();                                                    
 309                                                                                                          
 310     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 311                                                                                                          
 312     private LayoutInflater mInflater;                                                                    
 313                                                                                                          
 314     @Thunk Workspace mWorkspace;                                                                         
 315                                                                                                          
 316     private View mLauncherView;                                                                          
 317                                                                                                          
 318     private View mPageIndicators;                                                                        
 319                                                                                                          
 320     @Thunk DragLayer mDragLayer;                                                                         
 321                                                                                                          
 322     private DragController mDragController;                                                              
 323                                                                                                          
 324     private View mWeightWatcher;                                                                         
 325                                                                                                          
 326     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 327                                                                                                          
 328     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 329                                                                                                          
 330     @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                    
 331                                                                                                          
 332     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 333                                                                                                          
 334     private int mPendingAddWidgetId = -1;                                                                
 335                                                                                                          
 336     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 337                                                                                                          
 338     private Hotseat mHotseat;                                                                            
 339                                                                                                          
 340     private ViewGroup mOverviewPanel;                                                                    
 341                                                                                                          
 342     private View mAllAppsButton;                                                                         
 343                                                                                                          
 344     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 345                                                                                                          
 346     // Main container view for the all apps screen.                                                      
 347     // Main container view for the all apps screen.                                                      
 348     @Thunk AllAppsContainerView mAppsView;                                                               
 349                                                                                                          
 350     // Main container view and the model for the widget tray screen.                                     
 351     // Main container view and the model for the widget tray screen.                                     
 352     @Thunk WidgetsContainerView mWidgetsView;                                                            
 353                                                                                                          
 354     @Thunk WidgetsModel mWidgetsModel;                                                                   
 355                                                                                                          
 356     private boolean mAutoAdvanceRunning = false;                                                         
 357                                                                                                          
 358     private AppWidgetHostView mQsb;                                                                      
 359                                                                                                          
 360     private Bundle mSavedState;                                                                          
 361                                                                                                          
 362     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 363     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 364     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 365     private State mOnResumeState = State.NONE;                                                           
 366                                                                                                          
 367     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 368                                                                                                          
 369     @Thunk boolean mWorkspaceLoading = true;                                                             
 370                                                                                                          
 371     private boolean mPaused = true;                                                                      
 372                                                                                                          
 373     private boolean mRestoring;                                                                          
 374                                                                                                          
 375     private boolean mWaitingForResult;                                                                   
 376                                                                                                          
 377     private boolean mOnResumeNeedsLoad;                                                                  
 378                                                                                                          
 379     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 380                                                                                                          
 381     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 382                                                                                                          
 383     private Bundle mSavedInstanceState;                                                                  
 384                                                                                                          
 385     private LauncherModel mModel;                                                                        
 386                                                                                                          
 387     private IconCache mIconCache;                                                                        
 388                                                                                                          
 389     @Thunk boolean mUserPresent = true;                                                                  
 390                                                                                                          
 391     private boolean mVisible = false;                                                                    
 392                                                                                                          
 393     private boolean mHasFocus = false;                                                                   
 394                                                                                                          
 395     private boolean mAttached = false;                                                                   
 396                                                                                                          
 397     @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                       
 398                                                                                                          
 399     private static LongArrayMap<FolderInfo> sFolders = new LongArrayMap<>();                             
 400                                                                                                          
 401     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 402                                                                                                          
 403     // Related to the auto-advancing of widgets                                                          
 404     // Related to the auto-advancing of widgets                                                          
 405     private final int ADVANCE_MSG = 1;                                                                   
 406                                                                                                          
 407     private final int mAdvanceInterval = 20000;                                                          
 408                                                                                                          
 409     private final int mAdvanceStagger = 250;                                                             
 410                                                                                                          
 411     private long mAutoAdvanceSentTime;                                                                   
 412                                                                                                          
 413     private long mAutoAdvanceTimeLeft = -1;                                                              
 414                                                                                                          
 415     @Thunk                                                                                               
 416     HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<View, AppWidgetProviderInfo>(); 
 417                                                                                                          
 418     // Determines how long to wait after a rotation before restoring the screen orientation to           
 419     // match the sensor state.                                                                           
 420     // Determines how long to wait after a rotation before restoring the screen orientation to           
 421     // match the sensor state.                                                                           
 422     private final int mRestoreScreenOrientationDelay = 500;                                              
 423                                                                                                          
 424     @Thunk Drawable mWorkspaceBackgroundDrawable;                                                        
 425                                                                                                          
 426     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 427                                                                                                          
 428     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 429                                                                                                          
 430     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 431                                                                                                          
 432     static Date sDateStamp = new Date();                                                                 
 433                                                                                                          
 434     static DateFormat sDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);  
 435                                                                                                          
 436     static long sRunStart = System.currentTimeMillis();                                                  
 437                                                                                                          
 438     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 439                                                                                                          
 440     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 441     // it from the context.                                                                              
 442     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 443     // it from the context.                                                                              
 444     private SharedPreferences mSharedPrefs;                                                              
 445                                                                                                          
 446     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 447     // when we scroll to that page on resume.                                                            
 448     @Thunk                                                                                               
 449     ImageView mFolderIconImageView;                                                                      
 450                                                                                                          
 451     private Bitmap mFolderIconBitmap;                                                                    
 452                                                                                                          
 453     private Canvas mFolderIconCanvas;                                                                    
 454                                                                                                          
 455     private Rect mRectForFolderAnimation = new Rect();                                                   
 456                                                                                                          
 457     private DeviceProfile mDeviceProfile;                                                                
 458                                                                                                          
 459     // This is set to the view that launched the activity that navigated the user away from              
 460     // launcher. Since there is no callback for when the activity has finished launching, enable         
 461     // the press state and keep this reference to reset the press state when we return to launcher.      
 462     private BubbleTextView mWaitingForResume;                                                            
 463                                                                                                          
 464     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets = new HashMap<String, CustomAppWi🔵
 465                                                                                                          
 466     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 467                                                                                                          
 468     static {                                                                                             
 469         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 470             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 471         }                                                                                                
 472     }                                                                                                    
 473                                                                                                          
 474     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 475     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 476     private static Method sClipRevealMethod = null;                                                      
 477                                                                                                          
 478     static {                                                                                             
 479         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 480         try {                                                                                            
 481             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation", View.cl🔵
 482         } catch (java.lang.Exception e) {                                                                
 483             // Earlier version                                                                           
 484         }                                                                                                
 485     }                                                                                                    
 486                                                                                                          
 487     @Thunk                                                                                               
 488     Runnable mBuildLayersRunnable = new Runnable() {                                                     
 489         public void run() {                                                                              
 490             if (mWorkspace != null) {                                                                    
 491                 mWorkspace.buildPageHardwareLayers();                                                    
 492             }                                                                                            
 493         }                                                                                                
 494     };                                                                                                   
 495                                                                                                          
 496     private static PendingAddArguments sPendingAddItem;                                                  
 497                                                                                                          
 498     @Thunk                                                                                               
 499     static class PendingAddArguments {                                                                   
 500         int requestCode;                                                                                 
 501                                                                                                          
 502         Intent intent;                                                                                   
 503                                                                                                          
 504         long container;                                                                                  
 505                                                                                                          
 506         long screenId;                                                                                   
 507                                                                                                          
 508         int cellX;                                                                                       
 509                                                                                                          
 510         int cellY;                                                                                       
 511                                                                                                          
 512         int appWidgetId;                                                                                 
 513     }                                                                                                    
 514                                                                                                          
 515     private Stats mStats;                                                                                
 516                                                                                                          
 517     FocusIndicatorView mFocusHandler;                                                                    
 518                                                                                                          
 519     @Override                                                                                            
 520     protected void onCreate(Bundle savedInstanceState) {                                                 
 521         if (DEBUG_STRICT_MODE) {                                                                         
 522             StrictMode.setThreadPolicy(// or .detectAll() for all detectable problems                    
 523             new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().pe🔵
 524             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectL🔵
 525         }                                                                                                
 526         if (mLauncherCallbacks != null) {                                                                
 527             mLauncherCallbacks.preOnCreate();                                                            
 528         }                                                                                                
 529         super.onCreate(savedInstanceState);                                                              
 530         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 531         LauncherAppState app = LauncherAppState.getInstance();                                           
 532         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 533         // Load configuration-specific DeviceProfile                                                     
 534         mDeviceProfile = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LAND🔵
 535         // TODO: Move this to icon cache.                                                                
 536         Utilities.setIconSize(mDeviceProfile.iconSizePx);                                                
 537         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 538         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIV🔵
 539         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 540         mModel = app.setLauncher(this);                                                                  
 541         mIconCache = app.getIconCache();                                                                 
 542         mDragController = new DragController(this);                                                      
 543         mInflater = getLayoutInflater();                                                                 
 544         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 545         mStats = new Stats(this);                                                                        
 546         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 547         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 548         mAppWidgetHost.startListening();                                                                 
 549         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 550         // this also ensures that any synchronous binding below doesn't re-trigger another               
 551         // LauncherModel load.                                                                           
 552         mPaused = false;                                                                                 
 553         if (PROFILE_STARTUP) {                                                                           
 554             android.os.Debug.startMethodTracing(Environment.getExternalStorageDirectory() + "/launcher");
 555         }                                                                                                
 556         checkForLocaleChange();                                                                          
 557         setContentView(R.layout.launcher);                                                               
 558         setupViews();                                                                                    
 559         mDeviceProfile.layout(this);                                                                     
 560         registerContentObservers();                                                                      
 561         lockAllApps();                                                                                   
 562         mSavedState = savedInstanceState;                                                                
 563         restoreState(mSavedState);                                                                       
 564         if (PROFILE_STARTUP) {                                                                           
 565             android.os.Debug.stopMethodTracing();                                                        
 566         }                                                                                                
 567         if (!mRestoring) {                                                                               
 568             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 569                 // If the user leaves launcher, then we should just load items asynchronously when       
 570                 // they return.                                                                          
 571                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                      
 572             } else {                                                                                     
 573                 // We only load the page synchronously if the user rotates (or triggers a                
 574                 // configuration change) while launcher is in the foreground                             
 575                 mModel.startLoader(mWorkspace.getRestorePage());                                         
 576             }                                                                                            
 577         }                                                                                                
 578         // For handling default keys                                                                     
 579         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 580         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 581         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 582         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 583         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 584         unlockScreenOrientation(true);                                                                   
 585         if (mLauncherCallbacks != null) {                                                                
 586             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 587             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 588                 ViewStub stub = ((ViewStub) (findViewById(R.id.launcher_overlay_stub)));                 
 589                 mLauncherOverlayContainer = ((InsettableFrameLayout) (stub.inflate()));                  
 590                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(mLauncherOverlayContainer, m🔵
 591                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 592             }                                                                                            
 593         }                                                                                                
 594         if (shouldShowIntroScreen()) {                                                                   
 595             showIntroScreen();                                                                           
 596         } else {                                                                                         
 597             showFirstRunActivity();                                                                      
 598             showFirstRunClings();                                                                        
 599         }                                                                                                
 600     }                                                                                                    
 601                                                                                                          
 602     private LauncherCallbacks mLauncherCallbacks;                                                        
 603                                                                                                          
 604     public void onPostCreate(Bundle savedInstanceState) {                                                
 605         super.onPostCreate(savedInstanceState);                                                          
 606         if (mLauncherCallbacks != null) {                                                                
 607             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 608         }                                                                                                
 609     }                                                                                                    
 610                                                                                                          
 611     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 612         mLauncherCallbacks = callbacks;                                                                  
 613         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 614             @Override                                                                                    
 615             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 616                 if (LOGD) {                                                                              
 617                     Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);                               
 618                 }                                                                                        
 619                 mAppsView.setFixedBounds(bounds);                                                        
 620                 mWidgetsView.setFixedBounds(bounds);                                                     
 621             }                                                                                            
 622                                                                                                          
 623             @Override                                                                                    
 624             public void dismissAllApps() {                                                               
 625                 if (!DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
 626                     // Dismiss All Apps if we aren't already paused/invisible                            
 627                     if (!mPaused) {                                                                      
 628                         /* onCompleteRunnable */                                                         
 629                         /* notifyLauncherCallbacks */                                                    
 630                         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true, nul🔵
 631                     }                                                                                    
 632                 }                                                                                        
 633             }                                                                                            
 634         });                                                                                              
 635         return true;                                                                                     
 636     }                                                                                                    
 637                                                                                                          
 638     @Override                                                                                            
 639     public void onLauncherProviderChange() {                                                             
 640         if (mLauncherCallbacks != null) {                                                                
 641             mLauncherCallbacks.onLauncherProviderChange();                                               
 642         }                                                                                                
 643     }                                                                                                    
 644                                                                                                          
 645     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 646     protected boolean hasCustomContentToLeft() {                                                         
 647         if (mLauncherCallbacks != null) {                                                                
 648             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 649         }                                                                                                
 650         return false;                                                                                    
 651     }                                                                                                    
 652                                                                                                          
 653     /**                                                                                                  
 654      * To be overridden by subclasses to populate the custom content container and call                  
 655      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 656      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 657      */                                                                                                  
 658     protected void populateCustomContentContainer() {                                                    
 659         if (mLauncherCallbacks != null) {                                                                
 660             mLauncherCallbacks.populateCustomContentContainer();                                         
 661         }                                                                                                
 662     }                                                                                                    
 663                                                                                                          
 664     /**                                                                                                  
 665      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 666      * ensure the custom content page is added or removed if necessary.                                  
 667      */                                                                                                  
 668     protected void invalidateHasCustomContentToLeft() {                                                  
 669         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 670             // Not bound yet, wait for bindScreens to be called.                                         
 671             return;                                                                                      
 672         }                                                                                                
 673                                                                                                          
 674         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 675             // Create the custom content page and call the subclass to populate it.                      
 676             mWorkspace.createCustomContentContainer();                                                   
 677             populateCustomContentContainer();                                                            
 678         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 679             mWorkspace.removeCustomContentPage();                                                        
 680         }                                                                                                
 681     }                                                                                                    
 682                                                                                                          
 683     @Thunk                                                                                               
 684     void checkForLocaleChange() {                                                                        
 685         if (sLocaleConfiguration == null) {                                                              
 686             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 687                 @Override                                                                                
 688                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 689                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 690                     readConfiguration(Launcher.this, localeConfiguration);                               
 691                     return localeConfiguration;                                                          
 692                 }                                                                                        
 693                                                                                                          
 694                 @Override                                                                                
 695                 protected void onPostExecute(LocaleConfiguration result) {                               
 696                     sLocaleConfiguration = result;                                                       
 697                     checkForLocaleChange();// recursive, but now with a locale configuration             
 698                                                                                                          
 699                 }                                                                                        
 700             }.execute();                                                                                 
 701             return;                                                                                      
 702         }                                                                                                
 703         final Configuration configuration = getResources().getConfiguration();                           
 704         final String previousLocale = Launcher.sLocaleConfiguration.locale;                              
 705         final String locale = configuration.locale.toString();                                           
 706         final int previousMcc = Launcher.sLocaleConfiguration.mcc;                                       
 707         final int mcc = configuration.mcc;                                                               
 708         final int previousMnc = Launcher.sLocaleConfiguration.mnc;                                       
 709         final int mnc = configuration.mnc;                                                               
 710         boolean localeChanged = ((!locale.equals(previousLocale)) || (mcc != previousMcc)) || (mnc != pre🔵
 711         if (localeChanged) {                                                                             
 712             Launcher.sLocaleConfiguration.locale = locale;                                               
 713             Launcher.sLocaleConfiguration.mcc = mcc;                                                     
 714             Launcher.sLocaleConfiguration.mnc = mnc;                                                     
 715             mIconCache.flush();                                                                          
 716             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 717             new AsyncTask<Void, Void, Void>() {                                                          
 718                 public Void doInBackground(Void... args) {                                               
 719                     writeConfiguration(Launcher.this, localeConfiguration);                              
 720                     return null;                                                                         
 721                 }                                                                                        
 722             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) (null)));                        
 723         }                                                                                                
 724     }                                                                                                    
 725                                                                                                          
 726     @Thunk                                                                                               
 727     static class LocaleConfiguration {                                                                   
 728         public String locale;                                                                            
 729                                                                                                          
 730         public int mcc = -1;                                                                             
 731                                                                                                          
 732         public int mnc = -1;                                                                             
 733     }                                                                                                    
 734                                                                                                          
 735     @Thunk                                                                                               
 736     static void readConfiguration(Context context, LocaleConfiguration configuration) {                  
 737         DataInputStream in = null;                                                                       
 738         try {                                                                                            
 739             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 740             configuration.locale = in.readUTF();                                                         
 741             configuration.mcc = in.readInt();                                                            
 742             configuration.mnc = in.readInt();                                                            
 743         } catch (FileNotFoundException e) {                                                              
 744             // Ignore                                                                                    
 745         } catch (IOException e) {                                                                        
 746             // Ignore                                                                                    
 747         } finally {                                                                                      
 748             if (in != null) {                                                                            
 749                 try {                                                                                    
 750                     in.close();                                                                          
 751                 } catch (IOException e) {                                                                
 752                     // Ignore                                                                            
 753                 }                                                                                        
 754             }                                                                                            
 755         }                                                                                                
 756     }                                                                                                    
 757                                                                                                          
 758     @Thunk                                                                                               
 759     static void writeConfiguration(Context context, LocaleConfiguration configuration) {                 
 760         DataOutputStream out = null;                                                                     
 761         try {                                                                                            
 762             out = new DataOutputStream(context.openFileOutput(LauncherFiles.LAUNCHER_PREFERENCES, MODE_PR🔵
 763             out.writeUTF(configuration.locale);                                                          
 764             out.writeInt(configuration.mcc);                                                             
 765             out.writeInt(configuration.mnc);                                                             
 766             out.flush();                                                                                 
 767         } catch (FileNotFoundException e) {                                                              
 768             // Ignore                                                                                    
 769         } catch (IOException e) {                                                                        
 770             // noinspection ResultOfMethodCallIgnored                                                    
 771             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 772         } finally {                                                                                      
 773             if (out != null) {                                                                           
 774                 try {                                                                                    
 775                     out.close();                                                                         
 776                 } catch (IOException e) {                                                                
 777                     // Ignore                                                                            
 778                 }                                                                                        
 779             }                                                                                            
 780         }                                                                                                
 781     }                                                                                                    
 782                                                                                                          
 783     public Stats getStats() {                                                                            
 784         return mStats;                                                                                   
 785     }                                                                                                    
 786                                                                                                          
 787     public LayoutInflater getInflater() {                                                                
 788         return mInflater;                                                                                
 789     }                                                                                                    
 790                                                                                                          
 791     public boolean isDraggingEnabled() {                                                                 
 792         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 793         // that is subsequently removed from the workspace in startBinding().                            
 794         return !mModel.isLoadingWorkspace();                                                             
 795     }                                                                                                    
 796                                                                                                          
 797     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 798     public static int generateViewId() {                                                                 
 799         if (Build.VERSION.SDK_INT >= 17) {                                                               
 800             return View.generateViewId();                                                                
 801         } else {                                                                                         
 802             // View.generateViewId() is not available. The following fallback logic is a copy            
 803             // of its implementation.                                                                    
 804             for (;;) {                                                                                   
 805                 final int result = sNextGeneratedId.get();                                               
 806                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 807                 int newValue = result + 1;                                                               
 808                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 809                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 810                     return result;                                                                       
 811                 }                                                                                        
 812             }                                                                                            
 813         }                                                                                                
 814     }                                                                                                    
 815                                                                                                          
 816     public int getViewIdForItem(ItemInfo info) {                                                         
 817         // This cast is safe given the > 2B range for int.                                               
 818         int itemId = (int) info.id;                                                                      
 819         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 820             return mItemIdToViewId.get(itemId);                                                          
 821         }                                                                                                
 822         int viewId = generateViewId();                                                                   
 823         mItemIdToViewId.put(itemId, viewId);                                                             
 824         return viewId;                                                                                   
 825     }                                                                                                    
 826                                                                                                          
 827     /**                                                                                                  
 828      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 829      * a configuration step, this allows the proper animations to run after other transitions.           
 830      */                                                                                                  
 831     private long completeAdd(PendingAddArguments args) {                                                 
 832         long screenId = args.screenId;                                                                   
 833         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 834             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 835             // that the drop page actually exists.                                                       
 836             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 837         }                                                                                                
 838                                                                                                          
 839         switch (args.requestCode) {                                                                      
 840             case REQUEST_CREATE_SHORTCUT:                                                                
 841                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 842                         args.cellY);                                                                     
 843                 break;                                                                                   
 844             case REQUEST_CREATE_APPWIDGET:                                                               
 845                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 846                 break;                                                                                   
 847             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 848                 completeRestoreAppWidget(args.appWidgetId);                                              
 849                 break;                                                                                   
 850         }                                                                                                
 851         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 852         // if you turned the screen off and then back while in All Apps, Launcher would not              
 853         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 854         resetAddInfo();                                                                                  
 855         return screenId;                                                                                 
 856     }                                                                                                    
 857                                                                                                          
 858     private void handleActivityResult(final int requestCode, final int resultCode, final Intent data) {  
 859         // Reset the startActivity waiting flag                                                          
 860         setWaitingForResult(false);                                                                      
 861         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 862         mPendingAddWidgetId = -1;                                                                        
 863         Runnable exitSpringLoaded = new Runnable() {                                                     
 864             @Override                                                                                    
 865             public void run() {                                                                          
 866                 exitSpringLoadedDragModeDelayed(resultCode != RESULT_CANCELED, EXIT_SPRINGLOADED_MODE_SHO🔵
 867             }                                                                                            
 868         };                                                                                               
 869         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 870             final int appWidgetId = (data != null) ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID🔵
 871             if (resultCode == RESULT_CANCELED) {                                                         
 872                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 873                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMA🔵
 874             } else if (resultCode == RESULT_OK) {                                                        
 875                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null, mPendingAddWidgetInfo, ON_ACTIVITY_R🔵
 876             }                                                                                            
 877             return;                                                                                      
 878         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 879             if ((resultCode == RESULT_OK) && mWorkspace.isInOverviewMode()) {                            
 880                 showWorkspace(false);                                                                    
 881             }                                                                                            
 882             return;                                                                                      
 883         }                                                                                                
 884         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET) || (requestCode == REQUEST_CREATE_🔵
 885         final boolean workspaceLocked = isWorkspaceLocked();                                             
 886         // We have special handling for widgets                                                          
 887         if (isWidgetDrop) {                                                                              
 888             final int appWidgetId;                                                                       
 889             int widgetId = (data != null) ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -🔵
 890             if (widgetId < 0) {                                                                          
 891                 appWidgetId = pendingAddWidgetId;                                                        
 892             } else {                                                                                     
 893                 appWidgetId = widgetId;                                                                  
 894             }                                                                                            
 895             final int result;                                                                            
 896             if ((appWidgetId < 0) || (resultCode == RESULT_CANCELED)) {                                  
 897                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " + "returned from the widget🔵
 898                 result = RESULT_CANCELED;                                                                
 899                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 900                 final Runnable onComplete = new Runnable() {                                             
 901                     @Override                                                                            
 902                     public void run() {                                                                  
 903                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 904                     }                                                                                    
 905                 };                                                                                       
 906                 if (workspaceLocked) {                                                                   
 907                     // No need to remove the empty screen if we're mid-binding, as the                   
 908                     // the bind will not add the empty screen.                                           
 909                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 910                 } else {                                                                                 
 911                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, ON_ACTIVITY_RESULT_ANIMATI🔵
 912                 }                                                                                        
 913             } else if (!workspaceLocked) {                                                               
 914                 if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {         
 915                     // When the screen id represents an actual screen (as opposed to a rank)             
 916                     // we make sure that the drop page actually exists.                                  
 917                     mPendingAddInfo.screenId = ensurePendingDropLayoutExists(mPendingAddInfo.screenId);  
 918                 }                                                                                        
 919                 final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);      
 920                 dropLayout.setDropPending(true);                                                         
 921                 final Runnable onComplete = new Runnable() {                                             
 922                     @Override                                                                            
 923                     public void run() {                                                                  
 924                         completeTwoStageWidgetDrop(resultCode, appWidgetId);                             
 925                         dropLayout.setDropPending(false);                                                
 926                     }                                                                                    
 927                 };                                                                                       
 928                 mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, ON_ACTIVITY_RESULT_ANIMATION_D🔵
 929             } else {                                                                                     
 930                 PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId, mPending🔵
 931                 sPendingAddItem = args;                                                                  
 932             }                                                                                            
 933             return;                                                                                      
 934         }                                                                                                
 935         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 936             if (resultCode == RESULT_OK) {                                                               
 937                 // Update the widget view.                                                               
 938                 PendingAddArguments args = preparePendingAddArgs(requestCode, data, pendingAddWidgetId, m🔵
 939                 if (workspaceLocked) {                                                                   
 940                     sPendingAddItem = args;                                                              
 941                 } else {                                                                                 
 942                     completeAdd(args);                                                                   
 943                 }                                                                                        
 944             }                                                                                            
 945             // Leave the widget in the pending state if the user canceled the configure.                 
 946             return;                                                                                      
 947         }                                                                                                
 948         // The pattern used here is that a user PICKs a specific application,                            
 949         // which, depending on the target, might need to CREATE the actual target.                       
 950         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 951         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 952         if ((resultCode == RESULT_OK) && (mPendingAddInfo.container != ItemInfo.NO_ID)) {                
 953             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1, mPendingAddInfo🔵
 954             if (isWorkspaceLocked()) {                                                                   
 955                 sPendingAddItem = args;                                                                  
 956             } else {                                                                                     
 957                 completeAdd(args);                                                                       
 958                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMA🔵
 959             }                                                                                            
 960         } else if (resultCode == RESULT_CANCELED) {                                                      
 961             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMATION🔵
 962         }                                                                                                
 963         mDragLayer.clearAnimatedView();                                                                  
 964     }                                                                                                    
 965                                                                                                          
 966     @Override                                                                                            
 967     protected void onActivityResult(                                                                     
 968             final int requestCode, final int resultCode, final Intent data) {                            
 969         handleActivityResult(requestCode, resultCode, data);                                             
 970         if (mLauncherCallbacks != null) {                                                                
 971             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 972         }                                                                                                
 973     }                                                                                                    
 974                                                                                                          
 975     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 976             appWidgetId, ItemInfo info) {                                                                
 977         PendingAddArguments args = new PendingAddArguments();                                            
 978         args.requestCode = requestCode;                                                                  
 979         args.intent = data;                                                                              
 980         args.container = info.container;                                                                 
 981         args.screenId = info.screenId;                                                                   
 982         args.cellX = info.cellX;                                                                         
 983         args.cellY = info.cellY;                                                                         
 984         args.appWidgetId = appWidgetId;                                                                  
 985         return args;                                                                                     
 986     }                                                                                                    
 987                                                                                                          
 988     /**                                                                                                  
 989      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 990      *                                                                                                   
 991      * @param screenId the screen id to check                                                            
 992      * @return the new screen, or screenId if it exists                                                  
 993      */                                                                                                  
 994     private long ensurePendingDropLayoutExists(long screenId) {                                          
 995         CellLayout dropLayout =                                                                          
 996                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 997         if (dropLayout == null) {                                                                        
 998             // it's possible that the add screen was removed because it was                              
 999             // empty and a re-bind occurred                                                              
1000             mWorkspace.addExtraEmptyScreen();                                                            
1001             return mWorkspace.commitExtraEmptyScreen();                                                  
1002         } else {                                                                                         
1003             return screenId;                                                                             
1004         }                                                                                                
1005     }                                                                                                    
1006                                                                                                          
1007     @Thunk                                                                                               
1008     void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                       
1009         CellLayout cellLayout = ((CellLayout) (mWorkspace.getScreenWithId(mPendingAddInfo.screenId)));   
1010         Runnable onCompleteRunnable = null;                                                              
1011         int animationType = 0;                                                                           
1012         AppWidgetHostView boundWidget = null;                                                            
1013         if (resultCode == RESULT_OK) {                                                                   
1014             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
1015             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId, mPendingAddWidg🔵
1016             boundWidget = layout;                                                                        
1017             onCompleteRunnable = new Runnable() {                                                        
1018                 @Override                                                                                
1019                 public void run() {                                                                      
1020                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container, mPendingAddInfo.screenId🔵
1021                     exitSpringLoadedDragModeDelayed(resultCode != RESULT_CANCELED, EXIT_SPRINGLOADED_MODE🔵
1022                 }                                                                                        
1023             };                                                                                           
1024         } else if (resultCode == RESULT_CANCELED) {                                                      
1025             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
1026             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
1027         }                                                                                                
1028         if (mDragLayer.getAnimatedView() != null) {                                                      
1029             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout, ((DragView) (mDragLayer.getAnimated🔵
1030         } else if (onCompleteRunnable != null) {                                                         
1031             // The animated view may be null in the case of a rotation during widget configuration       
1032             onCompleteRunnable.run();                                                                    
1033         }                                                                                                
1034     }                                                                                                    
1035                                                                                                          
1036     @Override                                                                                            
1037     protected void onStop() {                                                                            
1038         super.onStop();                                                                                  
1039         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1040                                                                                                          
1041         if (mLauncherCallbacks != null) {                                                                
1042             mLauncherCallbacks.onStop();                                                                 
1043         }                                                                                                
1044     }                                                                                                    
1045                                                                                                          
1046     @Override                                                                                            
1047     protected void onStart() {                                                                           
1048         super.onStart();                                                                                 
1049         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1050                                                                                                          
1051         if (mLauncherCallbacks != null) {                                                                
1052             mLauncherCallbacks.onStart();                                                                
1053         }                                                                                                
1054     }                                                                                                    
1055                                                                                                          
1056     @Override                                                                                            
1057     protected void onResume() {                                                                          
1058         long startTime = 0;                                                                              
1059         if (DEBUG_RESUME_TIME) {                                                                         
1060             startTime = System.currentTimeMillis();                                                      
1061             Log.v(TAG, "Launcher.onResume()");                                                           
1062         }                                                                                                
1063         if (mLauncherCallbacks != null) {                                                                
1064             mLauncherCallbacks.preOnResume();                                                            
1065         }                                                                                                
1066         super.onResume();                                                                                
1067         // Restore the previous launcher state                                                           
1068         if (mOnResumeState == State.WORKSPACE) {                                                         
1069             showWorkspace(false);                                                                        
1070         } else if (mOnResumeState == State.APPS) {                                                       
1071             boolean launchedFromApp = mWaitingForResume != null;                                         
1072             // Don't update the predicted apps if the user is returning to launcher in the apps          
1073             // view after launching an app, as they may be depending on the UI to be static to           
1074             // switch to another app, otherwise, if it was                                               
1075             /* animated */                                                                               
1076             /* resetListToTop */                                                                         
1077                     /* updatePredictedApps */                                                            
1078             showAppsView(false, false, !launchedFromApp);                                                
1079         } else if (mOnResumeState == State.WIDGETS) {                                                    
1080             showWidgetsView(false, false);                                                               
1081         }                                                                                                
1082         mOnResumeState = State.NONE;                                                                     
1083         // Restore the apps state if we are in all apps                                                  
1084         if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                             
1085             // Otherwise, notify the callbacks if we are in all apps mode                                
1086             if (mState == State.APPS) {                                                                  
1087                 if (mLauncherCallbacks != null) {                                                        
1088                     mLauncherCallbacks.onAllAppsShown();                                                 
1089                 }                                                                                        
1090             }                                                                                            
1091         }                                                                                                
1092         // Background was set to gradient in onPause(), restore to transparent if in all apps.           
1093         setWorkspaceBackground(mState == State.WORKSPACE ? WORKSPACE_BACKGROUND_TRANSPARENT : WORKSPACE_B🔵
1094         mPaused = false;                                                                                 
1095         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1096             setWorkspaceLoading(true);                                                                   
1097             mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                          
1098             mRestoring = false;                                                                          
1099             mOnResumeNeedsLoad = false;                                                                  
1100         }                                                                                                
1101         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1102             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1103             // execute them here                                                                         
1104             long startTimeCallbacks = 0;                                                                 
1105             if (DEBUG_RESUME_TIME) {                                                                     
1106                 startTimeCallbacks = System.currentTimeMillis();                                         
1107             }                                                                                            
1108             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1109                 mBindOnResumeCallbacks.get(i).run();                                                     
1110             }                                                                                            
1111             mBindOnResumeCallbacks.clear();                                                              
1112             if (DEBUG_RESUME_TIME) {                                                                     
1113                 Log.d(TAG, "Time spent processing callbacks in onResume: " + (System.currentTimeMillis() 🔵
1114             }                                                                                            
1115         }                                                                                                
1116         if (mOnResumeCallbacks.size() > 0) {                                                             
1117             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1118                 mOnResumeCallbacks.get(i).run();                                                         
1119             }                                                                                            
1120             mOnResumeCallbacks.clear();                                                                  
1121         }                                                                                                
1122         // Reset the pressed state of icons that were locked in the press state while activities         
1123         // were launching                                                                                
1124         if (mWaitingForResume != null) {                                                                 
1125             // Resets the previous workspace icon press state                                            
1126             mWaitingForResume.setStayPressed(false);                                                     
1127         }                                                                                                
1128         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1129         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1130         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1131         // orientation.                                                                                  
1132         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1133         reinflateQSBIfNecessary();                                                                       
1134         if (DEBUG_RESUME_TIME) {                                                                         
1135             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1136         }                                                                                                
1137         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1138             // If we are resuming and the custom content is the current page, we call onShow().          
1139             // It is also poassible that onShow will instead be called slightly after first layout       
1140             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1141             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1142                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1143             }                                                                                            
1144         }                                                                                                
1145         updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());                                
1146         mWorkspace.onResume();                                                                           
1147         if (!isWorkspaceLoading()) {                                                                     
1148             // Process any items that were added while Launcher was away.                                
1149             InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                   
1150         }                                                                                                
1151         if (mLauncherCallbacks != null) {                                                                
1152             mLauncherCallbacks.onResume();                                                               
1153         }                                                                                                
1154     }                                                                                                    
1155                                                                                                          
1156     @Override                                                                                            
1157     protected void onPause() {                                                                           
1158         // Ensure that items added to Launcher are queued until Launcher returns                         
1159         InstallShortcutReceiver.enableInstallQueue();                                                    
1160         super.onPause();                                                                                 
1161         mPaused = true;                                                                                  
1162         mDragController.cancelDrag();                                                                    
1163         mDragController.resetLastGestureUpTime();                                                        
1164         // We call onHide() aggressively. The custom content callbacks should be able to                 
1165         // debounce excess onHide calls.                                                                 
1166         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1167             mWorkspace.getCustomContentCallbacks().onHide();                                             
1168         }                                                                                                
1169         if (mLauncherCallbacks != null) {                                                                
1170             mLauncherCallbacks.onPause();                                                                
1171         }                                                                                                
1172     }                                                                                                    
1173                                                                                                          
1174     public interface CustomContentCallbacks {                                                            
1175         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1176         // by a onResume or by scrolling otherwise.                                                      
1177         public abstract void onShow(boolean fromResume);                                                 
1178                                                                                                          
1179         // Custom content is completely hidden                                                           
1180         public abstract void onHide();                                                                   
1181                                                                                                          
1182         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1183         public abstract void onScrollProgressChanged(float progress);                                    
1184                                                                                                          
1185         // Indicates whether the user is allowed to scroll away from the custom content.                 
1186         public abstract boolean isScrollingAllowed();                                                    
1187     }                                                                                                    
1188                                                                                                          
1189     public interface LauncherOverlay {                                                                   
1190         /**                                                                                              
1191          * Touch interaction leading to overscroll has begun                                             
1192          */                                                                                              
1193         public abstract void onScrollInteractionBegin();                                                 
1194                                                                                                          
1195         /**                                                                                              
1196          * Touch interaction related to overscroll has ended                                             
1197          */                                                                                              
1198         public abstract void onScrollInteractionEnd();                                                   
1199                                                                                                          
1200         /**                                                                                              
1201          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1202          * screen (or in the case of RTL, the rightmost screen).                                         
1203          */                                                                                              
1204         public abstract void onScrollChange(int progress, boolean rtl);                                  
1205                                                                                                          
1206         /**                                                                                              
1207          * Screen has stopped scrolling                                                                  
1208          */                                                                                              
1209         public abstract void onScrollSettled();                                                          
1210                                                                                                          
1211         /**                                                                                              
1212          * This method can be called by the Launcher in order to force the LauncherOverlay               
1213          * to exit fully immersive mode.                                                                 
1214          */                                                                                              
1215         public abstract void forceExitFullImmersion();                                                   
1216     }                                                                                                    
1217                                                                                                          
1218     public interface LauncherAppsCallbacks {                                                             
1219         /**                                                                                              
1220          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1221          * any other views.                                                                              
1222          */                                                                                              
1223         public abstract void onAllAppsBoundsChanged(Rect bounds);                                        
1224                                                                                                          
1225         /**                                                                                              
1226          * Called to dismiss all apps if it is showing.                                                  
1227          */                                                                                              
1228         public abstract void dismissAllApps();                                                           
1229     }                                                                                                    
1230                                                                                                          
1231     public interface LauncherOverlayCallbacks {                                                          
1232         /**                                                                                              
1233          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1234          * however it doesn't modify any state within the launcher.                                      
1235          */                                                                                              
1236         public abstract boolean canEnterFullImmersion();                                                 
1237                                                                                                          
1238         /**                                                                                              
1239          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1240          * eg. by occupying the full screen and handling all touch events.                               
1241          *                                                                                               
1242          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1243         case, Launcher will modify any necessary state and assumes the overlay is                        
1244         handling all interaction. If false, the LauncherOverlay should cancel any                        
1245          */                                                                                              
1246         public abstract boolean enterFullImmersion();                                                    
1247                                                                                                          
1248         /**                                                                                              
1249          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1250          * full control over UI and state.                                                               
1251          */                                                                                              
1252         public abstract void exitFullImmersion();                                                        
1253     }                                                                                                    
1254                                                                                                          
1255     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1256         @Override                                                                                        
1257         public boolean canEnterFullImmersion() {                                                         
1258             return mState == State.WORKSPACE;                                                            
1259         }                                                                                                
1260                                                                                                          
1261         @Override                                                                                        
1262         public boolean enterFullImmersion() {                                                            
1263             if (mState == State.WORKSPACE) {                                                             
1264                 // When fully immersed, disregard any touches which fall through.                        
1265                 mDragLayer.setBlockTouch(true);                                                          
1266                 return true;                                                                             
1267             }                                                                                            
1268             return false;                                                                                
1269         }                                                                                                
1270                                                                                                          
1271         @Override                                                                                        
1272         public void exitFullImmersion() {                                                                
1273             mDragLayer.setBlockTouch(false);                                                             
1274         }                                                                                                
1275     }                                                                                                    
1276                                                                                                          
1277     protected boolean hasSettings() {                                                                    
1278         if (mLauncherCallbacks != null) {                                                                
1279             return mLauncherCallbacks.hasSettings();                                                     
1280         }                                                                                                
1281         return false;                                                                                    
1282     }                                                                                                    
1283                                                                                                          
1284     public void addToCustomContentPage(View customContent,                                               
1285             CustomContentCallbacks callbacks, String description) {                                      
1286         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1287     }                                                                                                    
1288                                                                                                          
1289     // The custom content needs to offset its content to account for the QSB                             
1290     public int getTopOffsetForCustomContent() {                                                          
1291         return mWorkspace.getPaddingTop();                                                               
1292     }                                                                                                    
1293                                                                                                          
1294     @Override                                                                                            
1295     public Object onRetainNonConfigurationInstance() {                                                   
1296         // Flag the loader to stop early before switching                                                
1297         if (mModel.isCurrentCallbacks(this)) {                                                           
1298             mModel.stopLoader();                                                                         
1299         }                                                                                                
1300         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1301         return Boolean.TRUE;                                                                             
1302     }                                                                                                    
1303                                                                                                          
1304     // We can't hide the IME if it was forced open.  So don't bother                                     
1305     @Override                                                                                            
1306     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1307         super.onWindowFocusChanged(hasFocus);                                                            
1308         mHasFocus = hasFocus;                                                                            
1309                                                                                                          
1310         if (mLauncherCallbacks != null) {                                                                
1311             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1312         }                                                                                                
1313     }                                                                                                    
1314                                                                                                          
1315     private boolean acceptFilter() {                                                                     
1316         final InputMethodManager inputManager = (InputMethodManager)                                     
1317                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1318         return !inputManager.isFullscreenMode();                                                         
1319     }                                                                                                    
1320                                                                                                          
1321     @Override                                                                                            
1322     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1323         final int uniChar = event.getUnicodeChar();                                                      
1324         final boolean handled = super.onKeyDown(keyCode, event);                                         
1325         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1326         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1327             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1328                     keyCode, event);                                                                     
1329             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1330                 // something usable has been typed - start a search                                      
1331                 // the typed text will be retrieved and cleared by                                       
1332                 // showSearchDialog()                                                                    
1333                 // If there are multiple keystrokes before the search dialog takes focus,                
1334                 // onSearchRequested() will be called for every keystroke,                               
1335                 // but it is idempotent, so it's fine.                                                   
1336                 return onSearchRequested();                                                              
1337             }                                                                                            
1338         }                                                                                                
1339                                                                                                          
1340         // Eat the long press event so the keyboard doesn't come up.                                     
1341         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1342             return true;                                                                                 
1343         }                                                                                                
1344                                                                                                          
1345         return handled;                                                                                  
1346     }                                                                                                    
1347                                                                                                          
1348     private String getTypedText() {                                                                      
1349         return mDefaultKeySsb.toString();                                                                
1350     }                                                                                                    
1351                                                                                                          
1352     private void clearTypedText() {                                                                      
1353         mDefaultKeySsb.clear();                                                                          
1354         mDefaultKeySsb.clearSpans();                                                                     
1355         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1356     }                                                                                                    
1357                                                                                                          
1358     /**                                                                                                  
1359      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1360      * State                                                                                             
1361      */                                                                                                  
1362     private static State intToState(int stateOrdinal) {                                                  
1363         State state = State.WORKSPACE;                                                                   
1364         final State[] stateValues = State.values();                                                      
1365         for (int i = 0; i < stateValues.length; i++) {                                                   
1366             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1367                 state = stateValues[i];                                                                  
1368                 break;                                                                                   
1369             }                                                                                            
1370         }                                                                                                
1371         return state;                                                                                    
1372     }                                                                                                    
1373                                                                                                          
1374     /**                                                                                                  
1375      * Restores the previous state, if it exists.                                                        
1376      *                                                                                                   
1377      * @param savedState The previous state.                                                             
1378      */                                                                                                  
1379     @SuppressWarnings("unchecked")                                                                       
1380     private void restoreState(Bundle savedState) {                                                       
1381         if (savedState == null) {                                                                        
1382             return;                                                                                      
1383         }                                                                                                
1384         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1385         if ((state == State.APPS) || (state == State.WIDGETS)) {                                         
1386             mOnResumeState = state;                                                                      
1387         }                                                                                                
1388         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, PagedView.INVALID_RESTORE_PAG🔵
1389         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1390             mWorkspace.setRestorePage(currentScreen);                                                    
1391         }                                                                                                
1392         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1393         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1394         if ((pendingAddContainer != ItemInfo.NO_ID) && (pendingAddScreen > (-1))) {                      
1395             mPendingAddInfo.container = pendingAddContainer;                                             
1396             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1397             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1398             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1399             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1400             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1401             AppWidgetProviderInfo info = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);
1402             mPendingAddWidgetInfo = (info == null) ? null : LauncherAppWidgetProviderInfo.fromProviderInf🔵
1403             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1404             setWaitingForResult(true);                                                                   
1405             mRestoring = true;                                                                           
1406         }                                                                                                
1407         mItemIdToViewId = ((HashMap<Integer, Integer>) (savedState.getSerializable(RUNTIME_STATE_VIEW_IDS🔵
1408     }                                                                                                    
1409                                                                                                          
1410     /**                                                                                                  
1411      * Finds all the views we need and configure them properly.                                          
1412      */                                                                                                  
1413     private void setupViews() {                                                                          
1414         final DragController dragController = mDragController;                                           
1415         mLauncherView = findViewById(R.id.launcher);                                                     
1416         mFocusHandler = ((FocusIndicatorView) (findViewById(R.id.focus_indicator)));                     
1417         mDragLayer = ((DragLayer) (findViewById(R.id.drag_layer)));                                      
1418         mWorkspace = ((Workspace) (mDragLayer.findViewById(R.id.workspace)));                            
1419         mWorkspace.setPageSwitchListener(this);                                                          
1420         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1421         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_L🔵
1422         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1423         // Setup the drag layer                                                                          
1424         mDragLayer.setup(this, dragController);                                                          
1425         // Setup the hotseat                                                                             
1426         mHotseat = ((Hotseat) (findViewById(R.id.hotseat)));                                             
1427         if (mHotseat != null) {                                                                          
1428             mHotseat.setOnLongClickListener(this);                                                       
1429         }                                                                                                
1430         mOverviewPanel = ((ViewGroup) (findViewById(R.id.overview_panel)));                              
1431         View widgetButton = findViewById(R.id.widget_button);                                            
1432         widgetButton.setOnClickListener(new OnClickListener() {                                          
1433             @Override                                                                                    
1434             public void onClick(View arg0) {                                                             
1435                 if (!mWorkspace.isSwitchingState()) {                                                    
1436                     onClickAddWidgetButton(arg0);                                                        
1437                 }                                                                                        
1438             }                                                                                            
1439         });                                                                                              
1440         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1441         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1442         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1443             @Override                                                                                    
1444             public void onClick(View arg0) {                                                             
1445                 if (!mWorkspace.isSwitchingState()) {                                                    
1446                     onClickWallpaperPicker(arg0);                                                        
1447                 }                                                                                        
1448             }                                                                                            
1449         });                                                                                              
1450         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1451         View settingsButton = findViewById(R.id.settings_button);                                        
1452         if (hasSettings()) {                                                                             
1453             settingsButton.setOnClickListener(new OnClickListener() {                                    
1454                 @Override                                                                                
1455                 public void onClick(View arg0) {                                                         
1456                     if (!mWorkspace.isSwitchingState()) {                                                
1457                         onClickSettingsButton(arg0);                                                     
1458                     }                                                                                    
1459                 }                                                                                        
1460             });                                                                                          
1461             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1462         } else {                                                                                         
1463             settingsButton.setVisibility(View.GONE);                                                     
1464         }                                                                                                
1465         mOverviewPanel.setAlpha(0.0F);                                                                   
1466         // Setup the workspace                                                                           
1467         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1468         mWorkspace.setOnLongClickListener(this);                                                         
1469         mWorkspace.setup(dragController);                                                                
1470         dragController.addDragListener(mWorkspace);                                                      
1471         // Get the search/delete bar                                                                     
1472         mSearchDropTargetBar = ((SearchDropTargetBar) (mDragLayer.findViewById(R.id.search_drop_target_ba🔵
1473         // Setup Apps                                                                                    
1474         mAppsView = ((AllAppsContainerView) (findViewById(R.id.apps_view)));                             
1475         if (isAllAppsSearchOverridden()) {                                                               
1476             mAppsView.hideHeaderBar();                                                                   
1477         }                                                                                                
1478         // Setup AppsCustomize                                                                           
1479         mWidgetsView = ((WidgetsContainerView) (findViewById(R.id.widgets_view)));                       
1480         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1481         dragController.setDragScoller(mWorkspace);                                                       
1482         dragController.setScrollView(mDragLayer);                                                        
1483         dragController.setMoveTarget(mWorkspace);                                                        
1484         dragController.addDropTarget(mWorkspace);                                                        
1485         if (mSearchDropTargetBar != null) {                                                              
1486             mSearchDropTargetBar.setup(this, dragController);                                            
1487             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1488         }                                                                                                
1489         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1490             Log.v(TAG, "adding WeightWatcher");                                                          
1491             mWeightWatcher = new WeightWatcher(this);                                                    
1492             mWeightWatcher.setAlpha(0.5F);                                                               
1493             ((FrameLayout) (mLauncherView)).addView(mWeightWatcher, new FrameLayout.LayoutParams(FrameLay🔵
1494             boolean show = shouldShowWeightWatcher();                                                    
1495             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1496         }                                                                                                
1497     }                                                                                                    
1498                                                                                                          
1499     /**                                                                                                  
1500      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1501      */                                                                                                  
1502     public void setAllAppsButton(View allAppsButton) {                                                   
1503         mAllAppsButton = allAppsButton;                                                                  
1504     }                                                                                                    
1505                                                                                                          
1506     public View getAllAppsButton() {                                                                     
1507         return mAllAppsButton;                                                                           
1508     }                                                                                                    
1509                                                                                                          
1510     /**                                                                                                  
1511      * Creates a view representing a shortcut.                                                           
1512      *                                                                                                   
1513      * @param info                                                                                       
1514      * 		The data structure describing the shortcut.                                                     
1515      */                                                                                                  
1516     View createShortcut(ShortcutInfo info) {                                                             
1517         return createShortcut(((ViewGroup) (mWorkspace.getChildAt(mWorkspace.getCurrentPage()))), info); 
1518     }                                                                                                    
1519                                                                                                          
1520     /**                                                                                                  
1521      * Creates a view representing a shortcut inflated from the specified resource.                      
1522      *                                                                                                   
1523      * @param parent The group the shortcut belongs to.                                                  
1524      * @param info The data structure describing the shortcut.                                           
1525      *                                                                                                   
1526      * @return A View inflated from layoutResId.                                                         
1527      */                                                                                                  
1528     public View createShortcut(ViewGroup parent, ShortcutInfo info) {                                    
1529         BubbleTextView favorite = ((BubbleTextView) (mInflater.inflate(R.layout.app_icon, parent, false))🔵
1530         favorite.applyFromShortcutInfo(info, mIconCache);                                                
1531         favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);                       
1532         favorite.setOnClickListener(this);                                                               
1533         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1534         return favorite;                                                                                 
1535     }                                                                                                    
1536                                                                                                          
1537     /**                                                                                                  
1538      * Add a shortcut to the workspace.                                                                  
1539      *                                                                                                   
1540      * @param data The intent describing the shortcut.                                                   
1541      * @param cellInfo The position on screen where to create the shortcut.                              
1542      */                                                                                                  
1543     private void completeAddShortcut(Intent data, long container, long screenId, int cellX, int cellY) { 
1544         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1545         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1546         CellLayout layout = getCellLayout(container, screenId);                                          
1547         ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(this, data);                      
1548         if (info == null) {                                                                              
1549             return;                                                                                      
1550         }                                                                                                
1551         final View view = createShortcut(info);                                                          
1552         boolean foundCellSpan = false;                                                                   
1553         // First we check if we already know the exact location where we want to add this item.          
1554         if ((cellX >= 0) && (cellY >= 0)) {                                                              
1555             cellXY[0] = cellX;                                                                           
1556             cellXY[1] = cellY;                                                                           
1557             foundCellSpan = true;                                                                        
1558             // If appropriate, either create a folder or add to an existing folder                       
1559             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0, true, null, nu🔵
1560                 return;                                                                                  
1561             }                                                                                            
1562             DragObject dragObject = new DragObject();                                                    
1563             dragObject.dragInfo = info;                                                                  
1564             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject, true)) {  
1565                 return;                                                                                  
1566             }                                                                                            
1567         } else if (touchXY != null) {                                                                    
1568             // when dragging and dropping, just find the closest free spot                               
1569             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1570             foundCellSpan = result != null;                                                              
1571         } else {                                                                                         
1572             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1573         }                                                                                                
1574         if (!foundCellSpan) {                                                                            
1575             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1576             return;                                                                                      
1577         }                                                                                                
1578         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1579         if (!mRestoring) {                                                                               
1580             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1, isWorkspaceLock🔵
1581         }                                                                                                
1582     }                                                                                                    
1583                                                                                                          
1584     private int[] getSpanForWidget(ComponentName component, int minWidth, int minHeight) {               
1585         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(this, component, null);              
1586         // We want to account for the extra amount of padding that we are adding to the widget           
1587         // to ensure that it gets the full amount of space that it has requested                         
1588         int requiredWidth = (minWidth + padding.left) + padding.right;                                   
1589         int requiredHeight = (minHeight + padding.top) + padding.bottom;                                 
1590         return CellLayout.rectToCell(this, requiredWidth, requiredHeight, null);                         
1591     }                                                                                                    
1592                                                                                                          
1593     public int[] getSpanForWidget(AppWidgetProviderInfo info) {                                          
1594         return getSpanForWidget(info.provider, info.minWidth, info.minHeight);                           
1595     }                                                                                                    
1596                                                                                                          
1597     public int[] getMinSpanForWidget(AppWidgetProviderInfo info) {                                       
1598         return getSpanForWidget(info.provider, info.minResizeWidth, info.minResizeHeight);               
1599     }                                                                                                    
1600                                                                                                          
1601     /**                                                                                                  
1602      * Add a widget to the workspace.                                                                    
1603      *                                                                                                   
1604      * @param appWidgetId The app widget id                                                              
1605      */                                                                                                  
1606     @Thunk                                                                                               
1607     void completeAddAppWidget(int appWidgetId, long container, long screenId, AppWidgetHostView hostView,🔵
1608         ItemInfo info = mPendingAddInfo;                                                                 
1609         if (appWidgetInfo == null) {                                                                     
1610             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, mAppWidgetManager.getApp🔵
1611         }                                                                                                
1612         if (appWidgetInfo.isCustomWidget) {                                                              
1613             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1614         }                                                                                                
1615         LauncherAppWidgetInfo launcherInfo;                                                              
1616         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1617         launcherInfo.spanX = info.spanX;                                                                 
1618         launcherInfo.spanY = info.spanY;                                                                 
1619         launcherInfo.minSpanX = info.minSpanX;                                                           
1620         launcherInfo.minSpanY = info.minSpanY;                                                           
1621         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1622         LauncherModel.addItemToDatabase(this, launcherInfo, container, screenId, info.cellX, info.cellY);
1623         if (!mRestoring) {                                                                               
1624             if (hostView == null) {                                                                      
1625                 // Perform actual inflation because we're live                                           
1626                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1627             } else {                                                                                     
1628                 // The AppWidgetHostView has already been inflated and instantiated                      
1629                 launcherInfo.hostView = hostView;                                                        
1630             }                                                                                            
1631             launcherInfo.hostView.setTag(launcherInfo);                                                  
1632             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1633             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1634             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX, info.cellY, la🔵
1635             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1636         }                                                                                                
1637         resetAddInfo();                                                                                  
1638     }                                                                                                    
1639                                                                                                          
1640     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1641         @Override                                                                                        
1642         public void onReceive(Context context, Intent intent) {                                          
1643             final String action = intent.getAction();                                                    
1644             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1645                 mUserPresent = false;                                                                    
1646                 mDragLayer.clearAllResizeFrames();                                                       
1647                 updateAutoAdvanceState();                                                                
1648                 // Reset AllApps to its initial state only if we are not in the middle of                
1649                 // processing a multi-step drop                                                          
1650                 if (((mAppsView != null) && (mWidgetsView != null)) && (mPendingAddInfo.container == Item🔵
1651                     showWorkspace(false);                                                                
1652                 }                                                                                        
1653             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1654                 mUserPresent = true;                                                                     
1655                 updateAutoAdvanceState();                                                                
1656             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1657                 mModel.resetLoadedState(false, true);                                                    
1658                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSP🔵
1659             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1660                 mModel.resetLoadedState(false, true);                                                    
1661                 mModel.startLoader(PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR_WORKSP🔵
1662             }                                                                                            
1663         }                                                                                                
1664     };                                                                                                   
1665                                                                                                          
1666     @Override                                                                                            
1667     public void onAttachedToWindow() {                                                                   
1668         super.onAttachedToWindow();                                                                      
1669         // Listen for broadcasts related to user-presence                                                
1670         final IntentFilter filter = new IntentFilter();                                                  
1671         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1672         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1673         // For handling managed profiles                                                                 
1674         if (ENABLE_DEBUG_INTENTS) {                                                                      
1675             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1676             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1677         }                                                                                                
1678         registerReceiver(mReceiver, filter);                                                             
1679         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1680         setupTransparentSystemBarsForLmp();                                                              
1681         mAttached = true;                                                                                
1682         mVisible = true;                                                                                 
1683     }                                                                                                    
1684                                                                                                          
1685     /**                                                                                                  
1686      * Sets up transparent navigation and status bars in LMP.                                            
1687      * This method is a no-op for other platform versions.                                               
1688      */                                                                                                  
1689     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1690     private void setupTransparentSystemBarsForLmp() {                                                    
1691         if (Utilities.isLmpOrAbove()) {                                                                  
1692             Window window = getWindow();                                                                 
1693             window.getAttributes().systemUiVisibility |= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM🔵
1694             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutPa🔵
1695             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1696             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1697             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1698         }                                                                                                
1699     }                                                                                                    
1700                                                                                                          
1701     @Override                                                                                            
1702     public void onDetachedFromWindow() {                                                                 
1703         super.onDetachedFromWindow();                                                                    
1704         mVisible = false;                                                                                
1705         if (mAttached) {                                                                                 
1706             unregisterReceiver(mReceiver);                                                               
1707             mAttached = false;                                                                           
1708         }                                                                                                
1709         updateAutoAdvanceState();                                                                        
1710     }                                                                                                    
1711                                                                                                          
1712     public void onWindowVisibilityChanged(int visibility) {                                              
1713         mVisible = visibility == View.VISIBLE;                                                           
1714         updateAutoAdvanceState();                                                                        
1715         // The following code used to be in onResume, but it turns out onResume is called when           
1716         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1717         // is a more appropriate event to handle                                                         
1718         if (mVisible) {                                                                                  
1719             if (!mWorkspaceLoading) {                                                                    
1720                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1721                 // We want to let Launcher draw itself at least once before we force it to build         
1722                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1723                 // apps is nice and speedy.                                                              
1724                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1725                     private boolean mStarted = false;                                                    
1726                                                                                                          
1727                     public void onDraw() {                                                               
1728                         if (mStarted) {                                                                  
1729                             return;                                                                      
1730                         }                                                                                
1731                         mStarted = true;                                                                 
1732                         // We delay the layer building a bit in order to give                            
1733                         // other message processing a time to run.  In particular                        
1734                         // this avoids a delay in hiding the IME if it was                               
1735                         // currently shown, because doing that may involve                               
1736                         // some communication back with the app.                                         
1737                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1738                         final ViewTreeObserver.OnDrawListener listener = this;                           
1739                         mWorkspace.post(new Runnable() {                                                 
1740                             public void run() {                                                          
1741                                 if ((mWorkspace != null) && (mWorkspace.getViewTreeObserver() != null)) {
1742                                     mWorkspace.getViewTreeObserver().removeOnDrawListener(listener);     
1743                                 }                                                                        
1744                             }                                                                            
1745                         });                                                                              
1746                         return;                                                                          
1747                     }                                                                                    
1748                 });                                                                                      
1749             }                                                                                            
1750             clearTypedText();                                                                            
1751         }                                                                                                
1752     }                                                                                                    
1753                                                                                                          
1754     @Thunk                                                                                               
1755     void sendAdvanceMessage(long delay) {                                                                
1756         mHandler.removeMessages(ADVANCE_MSG);                                                            
1757         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1758         mHandler.sendMessageDelayed(msg, delay);                                                         
1759         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1760     }                                                                                                    
1761                                                                                                          
1762     @Thunk                                                                                               
1763     void updateAutoAdvanceState() {                                                                      
1764         boolean autoAdvanceRunning = (mVisible && mUserPresent) && (!mWidgetsToAdvance.isEmpty());       
1765         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1766             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1767             if (autoAdvanceRunning) {                                                                    
1768                 long delay = (mAutoAdvanceTimeLeft == (-1)) ? mAdvanceInterval : mAutoAdvanceTimeLeft;   
1769                 sendAdvanceMessage(delay);                                                               
1770             } else {                                                                                     
1771                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1772                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval - (System.currentTimeMillis() - m🔵
1773                 }                                                                                        
1774                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1775                 mHandler.removeMessages(0);// Remove messages sent using postDelayed()                   
1776                                                                                                          
1777             }                                                                                            
1778         }                                                                                                
1779     }                                                                                                    
1780                                                                                                          
1781     private final Handler mHandler = new Handler() {                                                     
1782         @Override                                                                                        
1783         public void handleMessage(Message msg) {                                                         
1784             if (msg.what == ADVANCE_MSG) {                                                               
1785                 int i = 0;                                                                               
1786                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1787                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1788                     final int delay = mAdvanceStagger * i;                                               
1789                     if (v instanceof Advanceable) {                                                      
1790                        postDelayed(new Runnable() {                                                      
1791                            public void run() {                                                           
1792                                ((Advanceable) v).advance();                                              
1793                            }                                                                             
1794                        }, delay);                                                                        
1795                     }                                                                                    
1796                     i++;                                                                                 
1797                 }                                                                                        
1798                 sendAdvanceMessage(mAdvanceInterval);                                                    
1799             }                                                                                            
1800         }                                                                                                
1801     };                                                                                                   
1802                                                                                                          
1803     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1804         if ((appWidgetInfo == null) || (appWidgetInfo.autoAdvanceViewId == (-1))) {                      
1805             return;                                                                                      
1806         }                                                                                                
1807         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1808         if (v instanceof Advanceable) {                                                                  
1809             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1810             ((Advanceable) (v)).fyiWillBeAdvancedByHostKThx();                                           
1811             updateAutoAdvanceState();                                                                    
1812         }                                                                                                
1813     }                                                                                                    
1814                                                                                                          
1815     void removeWidgetToAutoAdvance(View hostView) {                                                      
1816         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1817             mWidgetsToAdvance.remove(hostView);                                                          
1818             updateAutoAdvanceState();                                                                    
1819         }                                                                                                
1820     }                                                                                                    
1821                                                                                                          
1822     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1823         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1824         launcherInfo.hostView = null;                                                                    
1825     }                                                                                                    
1826                                                                                                          
1827     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1828         int strId = (isHotseatLayout) ? R.string.hotseat_out_of_space : R.string.out_of_space;           
1829         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1830     }                                                                                                    
1831                                                                                                          
1832     public DragLayer getDragLayer() {                                                                    
1833         return mDragLayer;                                                                               
1834     }                                                                                                    
1835                                                                                                          
1836     public AllAppsContainerView getAppsView() {                                                          
1837         return mAppsView;                                                                                
1838     }                                                                                                    
1839                                                                                                          
1840     public WidgetsContainerView getWidgetsView() {                                                       
1841         return mWidgetsView;                                                                             
1842     }                                                                                                    
1843                                                                                                          
1844     public Workspace getWorkspace() {                                                                    
1845         return mWorkspace;                                                                               
1846     }                                                                                                    
1847                                                                                                          
1848     public Hotseat getHotseat() {                                                                        
1849         return mHotseat;                                                                                 
1850     }                                                                                                    
1851                                                                                                          
1852     public ViewGroup getOverviewPanel() {                                                                
1853         return mOverviewPanel;                                                                           
1854     }                                                                                                    
1855                                                                                                          
1856     public SearchDropTargetBar getSearchBar() {                                                          
1857         return mSearchDropTargetBar;                                                                     
1858     }                                                                                                    
1859                                                                                                          
1860     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1861         return mAppWidgetHost;                                                                           
1862     }                                                                                                    
1863                                                                                                          
1864     public LauncherModel getModel() {                                                                    
1865         return mModel;                                                                                   
1866     }                                                                                                    
1867                                                                                                          
1868     protected SharedPreferences getSharedPrefs() {                                                       
1869         return mSharedPrefs;                                                                             
1870     }                                                                                                    
1871                                                                                                          
1872     public DeviceProfile getDeviceProfile() {                                                            
1873         return mDeviceProfile;                                                                           
1874     }                                                                                                    
1875                                                                                                          
1876     public void closeSystemDialogs() {                                                                   
1877         getWindow().closeAllPanels();                                                                    
1878                                                                                                          
1879         // Whatever we were doing is hereby canceled.                                                    
1880         setWaitingForResult(false);                                                                      
1881     }                                                                                                    
1882                                                                                                          
1883     @Override                                                                                            
1884     protected void onNewIntent(Intent intent) {                                                          
1885         long startTime = 0;                                                                              
1886         if (DEBUG_RESUME_TIME) {                                                                         
1887             startTime = System.currentTimeMillis();                                                      
1888         }                                                                                                
1889         super.onNewIntent(intent);                                                                       
1890         // Close the menu                                                                                
1891         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1892             // also will cancel mWaitingForResult.                                                       
1893             closeSystemDialogs();                                                                        
1894             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT🔵
1895             if (mWorkspace == null) {                                                                    
1896                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1897                 return;                                                                                  
1898             }                                                                                            
1899             Folder openFolder = mWorkspace.getOpenFolder();                                              
1900             // In all these cases, only animate if we're already on home                                 
1901             mWorkspace.exitWidgetResizeMode();                                                           
1902             boolean moveToDefaultScreen = (mLauncherCallbacks != null) ? mLauncherCallbacks.shouldMoveToD🔵
1903             if ((((alreadyOnHome && (mState == State.WORKSPACE)) && (!mWorkspace.isTouchActive())) && (op🔵
1904                 mWorkspace.moveToDefaultScreen(true);                                                    
1905             }                                                                                            
1906             closeFolder();                                                                               
1907             exitSpringLoadedDragMode();                                                                  
1908             // If we are already on home, then just animate back to the workspace,                       
1909             // otherwise, just wait until onResume to set the state back to Workspace                    
1910             if (alreadyOnHome) {                                                                         
1911                 showWorkspace(true);                                                                     
1912             } else {                                                                                     
1913                 mOnResumeState = State.WORKSPACE;                                                        
1914             }                                                                                            
1915             final View v = getWindow().peekDecorView();                                                  
1916             if ((v != null) && (v.getWindowToken() != null)) {                                           
1917                 InputMethodManager imm = ((InputMethodManager) (getSystemService(INPUT_METHOD_SERVICE)));
1918                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1919             }                                                                                            
1920             // Reset the apps view                                                                       
1921             if ((!alreadyOnHome) && (mAppsView != null)) {                                               
1922                 mAppsView.scrollToTop();                                                                 
1923             }                                                                                            
1924             // Reset the widgets view                                                                    
1925             if ((!alreadyOnHome) && (mWidgetsView != null)) {                                            
1926                 mWidgetsView.scrollToTop();                                                              
1927             }                                                                                            
1928             if (mLauncherCallbacks != null) {                                                            
1929                 mLauncherCallbacks.onHomeIntent();                                                       
1930             }                                                                                            
1931         }                                                                                                
1932         if (DEBUG_RESUME_TIME) {                                                                         
1933             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1934         }                                                                                                
1935         if (mLauncherCallbacks != null) {                                                                
1936             mLauncherCallbacks.onNewIntent(intent);                                                      
1937         }                                                                                                
1938     }                                                                                                    
1939                                                                                                          
1940     @Override                                                                                            
1941     public void onRestoreInstanceState(Bundle state) {                                                   
1942         super.onRestoreInstanceState(state);                                                             
1943         for (int page: mSynchronouslyBoundPages) {                                                       
1944             mWorkspace.restoreInstanceStateForChild(page);                                               
1945         }                                                                                                
1946     }                                                                                                    
1947                                                                                                          
1948     @Override                                                                                            
1949     protected void onSaveInstanceState(Bundle outState) {                                                
1950         if (mWorkspace.getChildCount() > 0) {                                                            
1951             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getCurrentPageOffsetFromCustomConten🔵
1952         }                                                                                                
1953         super.onSaveInstanceState(outState);                                                             
1954         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1955         // We close any open folder since it will not be re-opened, and we need to make sure             
1956         // this state is reflected.                                                                      
1957         closeFolder();                                                                                   
1958         if (((mPendingAddInfo.container != ItemInfo.NO_ID) && (mPendingAddInfo.screenId > (-1))) && mWait🔵
1959             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1960             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1961             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1962             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1963             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1964             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1965             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1966             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1967         }                                                                                                
1968         // Save the current widgets tray?                                                                
1969         // TODO(hyunyoungs)                                                                              
1970         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1971         if (mLauncherCallbacks != null) {                                                                
1972             mLauncherCallbacks.onSaveInstanceState(outState);                                            
1973         }                                                                                                
1974     }                                                                                                    
1975                                                                                                          
1976     @Override                                                                                            
1977     public void onDestroy() {                                                                            
1978         super.onDestroy();                                                                               
1979         // Remove all pending runnables                                                                  
1980         mHandler.removeMessages(ADVANCE_MSG);                                                            
1981         mHandler.removeMessages(0);                                                                      
1982         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
1983         // Stop callbacks from LauncherModel                                                             
1984         LauncherAppState app = LauncherAppState.getInstance();                                           
1985         // It's possible to receive onDestroy after a new Launcher activity has                          
1986         // been created. In this case, don't interfere with the new Launcher.                            
1987         if (mModel.isCurrentCallbacks(this)) {                                                           
1988             mModel.stopLoader();                                                                         
1989             app.setLauncher(null);                                                                       
1990         }                                                                                                
1991         try {                                                                                            
1992             mAppWidgetHost.stopListening();                                                              
1993         } catch (java.lang.NullPointerException ex) {                                                    
1994             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
1995         }                                                                                                
1996         mAppWidgetHost = null;                                                                           
1997         mWidgetsToAdvance.clear();                                                                       
1998         TextKeyListener.getInstance().release();                                                         
1999         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2000         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2001         mDragLayer.clearAllResizeFrames();                                                               
2002         ((ViewGroup) (mWorkspace.getParent())).removeAllViews();                                         
2003         mWorkspace.removeAllWorkspaceScreens();                                                          
2004         mWorkspace = null;                                                                               
2005         mDragController = null;                                                                          
2006         LauncherAnimUtils.onDestroyActivity();                                                           
2007         if (mLauncherCallbacks != null) {                                                                
2008             mLauncherCallbacks.onDestroy();                                                              
2009         }                                                                                                
2010     }                                                                                                    
2011                                                                                                          
2012     public DragController getDragController() {                                                          
2013         return mDragController;                                                                          
2014     }                                                                                                    
2015                                                                                                          
2016     @Override                                                                                            
2017     public void startActivityForResult(Intent intent, int requestCode) {                                 
2018         onStartForResult(requestCode);                                                                   
2019         super.startActivityForResult(intent, requestCode);                                               
2020     }                                                                                                    
2021                                                                                                          
2022     @Override                                                                                            
2023     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2024             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2025         onStartForResult(requestCode);                                                                   
2026         try {                                                                                            
2027             super.startIntentSenderForResult(intent, requestCode,                                        
2028                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2029         } catch (IntentSender.SendIntentException e) {                                                   
2030             throw new ActivityNotFoundException();                                                       
2031         }                                                                                                
2032     }                                                                                                    
2033                                                                                                          
2034     private void onStartForResult(int requestCode) {                                                     
2035         if (requestCode >= 0) {                                                                          
2036             setWaitingForResult(true);                                                                   
2037         }                                                                                                
2038     }                                                                                                    
2039                                                                                                          
2040     /**                                                                                                  
2041      * Indicates that we want global search for this activity by setting the globalSearch                
2042      * argument for {@link #startSearch} to true.                                                        
2043      */                                                                                                  
2044     @Override                                                                                            
2045     public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData, boolea🔵
2046         if (initialQuery == null) {                                                                      
2047             // Use any text typed in the launcher as the initial query                                   
2048             initialQuery = getTypedText();                                                               
2049         }                                                                                                
2050         if (appSearchData == null) {                                                                     
2051             appSearchData = new Bundle();                                                                
2052             appSearchData.putString("source", "launcher-search");                                        
2053         }                                                                                                
2054         Rect sourceBounds = new Rect();                                                                  
2055         if (mSearchDropTargetBar != null) {                                                              
2056             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2057         }                                                                                                
2058         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery, appSearchData, sourc🔵
2059         if (clearTextImmediately) {                                                                      
2060             clearTypedText();                                                                            
2061         }                                                                                                
2062         // We need to show the workspace after starting the search                                       
2063         showWorkspace(true);                                                                             
2064     }                                                                                                    
2065                                                                                                          
2066     /**                                                                                                  
2067      * Start a text search.                                                                              
2068      *                                                                                                   
2069      * @return {@code true} if the search will start immediately, so any further keypresses              
2070      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2071      * to buffer keypresses.                                                                             
2072      */                                                                                                  
2073     public boolean startSearch(String initialQuery,                                                      
2074             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2075         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2076             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2077                     sourceBounds);                                                                       
2078         }                                                                                                
2079                                                                                                          
2080         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2081                 appSearchData, sourceBounds);                                                            
2082         return false;                                                                                    
2083     }                                                                                                    
2084                                                                                                          
2085     /**                                                                                                  
2086      * Starts the global search activity. This code is a copied from SearchManager                       
2087      */                                                                                                  
2088     private void startGlobalSearch(String initialQuery,                                                  
2089             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2090         final SearchManager searchManager =                                                              
2091             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2092         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2093         if (globalSearchActivity == null) {                                                              
2094             Log.w(TAG, "No global search activity found.");                                              
2095             return;                                                                                      
2096         }                                                                                                
2097         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2098         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2099         intent.setComponent(globalSearchActivity);                                                       
2100         // Make sure that we have a Bundle to put source in                                              
2101         if (appSearchData == null) {                                                                     
2102             appSearchData = new Bundle();                                                                
2103         } else {                                                                                         
2104             appSearchData = new Bundle(appSearchData);                                                   
2105         }                                                                                                
2106         // Set source to package name of app that starts global search if not set already.               
2107         if (!appSearchData.containsKey("source")) {                                                      
2108             appSearchData.putString("source", getPackageName());                                         
2109         }                                                                                                
2110         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2111         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2112             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2113         }                                                                                                
2114         if (selectInitialQuery) {                                                                        
2115             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2116         }                                                                                                
2117         intent.setSourceBounds(sourceBounds);                                                            
2118         try {                                                                                            
2119             startActivity(intent);                                                                       
2120         } catch (ActivityNotFoundException ex) {                                                         
2121             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2122         }                                                                                                
2123     }                                                                                                    
2124                                                                                                          
2125     public boolean isOnCustomContent() {                                                                 
2126         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2127     }                                                                                                    
2128                                                                                                          
2129     @Override                                                                                            
2130     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2131         super.onPrepareOptionsMenu(menu);                                                                
2132         if (!isOnCustomContent()) {                                                                      
2133             // Close any open folders                                                                    
2134             closeFolder();                                                                               
2135             // Stop resizing any widgets                                                                 
2136             mWorkspace.exitWidgetResizeMode();                                                           
2137             if (!mWorkspace.isInOverviewMode()) {                                                        
2138                 // Show the overview mode                                                                
2139                 showOverviewMode(true);                                                                  
2140             } else {                                                                                     
2141                 showWorkspace(true);                                                                     
2142             }                                                                                            
2143         }                                                                                                
2144         if (mLauncherCallbacks != null) {                                                                
2145             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2146         }                                                                                                
2147                                                                                                          
2148         return false;                                                                                    
2149     }                                                                                                    
2150                                                                                                          
2151     @Override                                                                                            
2152     public boolean onSearchRequested() {                                                                 
2153         startSearch(null, false, null, true);                                                            
2154         // Use a custom animation for launching search                                                   
2155         return true;                                                                                     
2156     }                                                                                                    
2157                                                                                                          
2158     public boolean isWorkspaceLocked() {                                                                 
2159         return mWorkspaceLoading || mWaitingForResult;                                                   
2160     }                                                                                                    
2161                                                                                                          
2162     public boolean isWorkspaceLoading() {                                                                
2163         return mWorkspaceLoading;                                                                        
2164     }                                                                                                    
2165                                                                                                          
2166     private void setWorkspaceLoading(boolean value) {                                                    
2167         boolean isLocked = isWorkspaceLocked();                                                          
2168         mWorkspaceLoading = value;                                                                       
2169         if (isLocked != isWorkspaceLocked()) {                                                           
2170             onWorkspaceLockedChanged();                                                                  
2171         }                                                                                                
2172     }                                                                                                    
2173                                                                                                          
2174     private void setWaitingForResult(boolean value) {                                                    
2175         boolean isLocked = isWorkspaceLocked();                                                          
2176         mWaitingForResult = value;                                                                       
2177         if (isLocked != isWorkspaceLocked()) {                                                           
2178             onWorkspaceLockedChanged();                                                                  
2179         }                                                                                                
2180     }                                                                                                    
2181                                                                                                          
2182     protected void onWorkspaceLockedChanged() {                                                          
2183         if (mLauncherCallbacks != null) {                                                                
2184             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2185         }                                                                                                
2186     }                                                                                                    
2187                                                                                                          
2188     private void resetAddInfo() {                                                                        
2189         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2190         mPendingAddInfo.screenId = -1;                                                                   
2191         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2192         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2193         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2194         mPendingAddInfo.dropPos = null;                                                                  
2195     }                                                                                                    
2196                                                                                                          
2197     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2198             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2199         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2200     }                                                                                                    
2201                                                                                                          
2202     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2203             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2204             int delay) {                                                                                 
2205         if (appWidgetInfo.configure != null) {                                                           
2206             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2207             mPendingAddWidgetId = appWidgetId;                                                           
2208                                                                                                          
2209             // Launch over to configure widget, if needed                                                
2210             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2211                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2212                                                                                                          
2213         } else {                                                                                         
2214             // Otherwise just add it                                                                     
2215             Runnable onComplete = new Runnable() {                                                       
2216                 @Override                                                                                
2217                 public void run() {                                                                      
2218                     // Exit spring loaded mode if necessary after adding the widget                      
2219                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2220                             null);                                                                       
2221                 }                                                                                        
2222             };                                                                                           
2223             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2224                     appWidgetInfo);                                                                      
2225             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2226         }                                                                                                
2227     }                                                                                                    
2228                                                                                                          
2229     protected void moveToCustomContentScreen(boolean animate) {                                          
2230         // Close any folders that may be open.                                                           
2231         closeFolder();                                                                                   
2232         mWorkspace.moveToCustomContentScreen(animate);                                                   
2233     }                                                                                                    
2234                                                                                                          
2235     public void addPendingItem(PendingAddItemInfo info, long container, long screenId, int[] cell, int sp🔵
2236         switch (info.itemType) {                                                                         
2237             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET :                                 
2238             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET :                                        
2239                 int[] span = new int[2];                                                                 
2240                 span[0] = spanX;                                                                         
2241                 span[1] = spanY;                                                                         
2242                 addAppWidgetFromDrop(((PendingAddWidgetInfo) (info)), container, screenId, cell, span);  
2243                 break;                                                                                   
2244             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT :                                         
2245                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2246                 break;                                                                                   
2247             default :                                                                                    
2248                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2249         }                                                                                                
2250     }                                                                                                    
2251                                                                                                          
2252     /**                                                                                                  
2253      * Process a shortcut drop.                                                                          
2254      *                                                                                                   
2255      * @param componentName The name of the component                                                    
2256      * @param screenId The ID of the screen where it should be added                                     
2257      * @param cell The cell it should be added to, optional                                              
2258      */                                                                                                  
2259     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2260             int[] cell) {                                                                                
2261         resetAddInfo();                                                                                  
2262         mPendingAddInfo.container = container;                                                           
2263         mPendingAddInfo.screenId = screenId;                                                             
2264         mPendingAddInfo.dropPos = null;                                                                  
2265                                                                                                          
2266         if (cell != null) {                                                                              
2267             mPendingAddInfo.cellX = cell[0];                                                             
2268             mPendingAddInfo.cellY = cell[1];                                                             
2269         }                                                                                                
2270                                                                                                          
2271         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2272         createShortcutIntent.setComponent(componentName);                                                
2273         processShortcut(createShortcutIntent);                                                           
2274     }                                                                                                    
2275                                                                                                          
2276     /**                                                                                                  
2277      * Process a widget drop.                                                                            
2278      *                                                                                                   
2279      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2280      * @param screenId The ID of the screen where it should be added                                     
2281      * @param cell The cell it should be added to, optional                                              
2282      */                                                                                                  
2283     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId, int[] cel🔵
2284         resetAddInfo();                                                                                  
2285         mPendingAddInfo.container = info.container = container;                                          
2286         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2287         mPendingAddInfo.dropPos = null;                                                                  
2288         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2289         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2290         if (cell != null) {                                                                              
2291             mPendingAddInfo.cellX = cell[0];                                                             
2292             mPendingAddInfo.cellY = cell[1];                                                             
2293         }                                                                                                
2294         if (span != null) {                                                                              
2295             mPendingAddInfo.spanX = span[0];                                                             
2296             mPendingAddInfo.spanY = span[1];                                                             
2297         }                                                                                                
2298         AppWidgetHostView hostView = info.boundWidget;                                                   
2299         int appWidgetId;                                                                                 
2300         if (hostView != null) {                                                                          
2301             appWidgetId = hostView.getAppWidgetId();                                                     
2302             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2303         } else {                                                                                         
2304             // In this case, we either need to start an activity to get permission to bind               
2305             // the widget, or we need to start an activity to configure the widget, or both.             
2306             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2307             Bundle options = info.bindOptions;                                                           
2308             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.info, options)🔵
2309             if (success) {                                                                               
2310                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2311             } else {                                                                                     
2312                 mPendingAddWidgetInfo = info.info;                                                       
2313                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2314                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2315                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2316                 mAppWidgetManager.getUser(mPendingAddWidgetInfo).addToIntent(intent, AppWidgetManager.EXT🔵
2317                 // TODO: we need to make sure that this accounts for the options bundle.                 
2318                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2319                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2320             }                                                                                            
2321         }                                                                                                
2322     }                                                                                                    
2323                                                                                                          
2324     void processShortcut(Intent intent) {                                                                
2325         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2326     }                                                                                                    
2327                                                                                                          
2328     void processWallpaper(Intent intent) {                                                               
2329         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2330     }                                                                                                    
2331                                                                                                          
2332     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX, int cellY) { 
2333         final FolderInfo folderInfo = new FolderInfo();                                                  
2334         folderInfo.title = getText(R.string.folder_name);                                                
2335         // Update the model                                                                              
2336         LauncherModel.addItemToDatabase(this, folderInfo, container, screenId, cellX, cellY);            
2337         sFolders.put(folderInfo.id, folderInfo);                                                         
2338         // Create the view                                                                               
2339         FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCa🔵
2340         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1, isWorkspaceLocked()); 
2341         // Force measure the new folder icon                                                             
2342         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2343         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2344         return newFolder;                                                                                
2345     }                                                                                                    
2346                                                                                                          
2347     void removeFolder(FolderInfo folder) {                                                               
2348         sFolders.remove(folder.id);                                                                      
2349     }                                                                                                    
2350                                                                                                          
2351     /**                                                                                                  
2352      * Registers various content observers. The current implementation registers                         
2353      * only a favorites observer to keep track of the favorites applications.                            
2354      */                                                                                                  
2355     private void registerContentObservers() {                                                            
2356         ContentResolver resolver = getContentResolver();                                                 
2357         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2358                 true, mWidgetObserver);                                                                  
2359     }                                                                                                    
2360                                                                                                          
2361     @Override                                                                                            
2362     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2363         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2364             switch (event.getKeyCode()) {                                                                
2365                 case KeyEvent.KEYCODE_HOME:                                                              
2366                     return true;                                                                         
2367                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2368                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2369                         dumpState();                                                                     
2370                         return true;                                                                     
2371                     }                                                                                    
2372                     break;                                                                               
2373             }                                                                                            
2374         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2375             switch (event.getKeyCode()) {                                                                
2376                 case KeyEvent.KEYCODE_HOME:                                                              
2377                     return true;                                                                         
2378             }                                                                                            
2379         }                                                                                                
2380                                                                                                          
2381         return super.dispatchKeyEvent(event);                                                            
2382     }                                                                                                    
2383                                                                                                          
2384     @Override                                                                                            
2385     public void onBackPressed() {                                                                        
2386         if ((mLauncherCallbacks != null) && mLauncherCallbacks.handleBackPressed()) {                    
2387             return;                                                                                      
2388         }                                                                                                
2389         LauncherAccessibilityDelegate delegate = LauncherAppState.getInstance().getAccessibilityDelegate(🔵
2390         if ((delegate != null) && delegate.onBackPressed()) {                                            
2391             return;                                                                                      
2392         }                                                                                                
2393         if (isAppsViewVisible()) {                                                                       
2394             showWorkspace(true);                                                                         
2395         } else if (isWidgetsViewVisible()) {                                                             
2396             showOverviewMode(true);                                                                      
2397         } else if (mWorkspace.isInOverviewMode()) {                                                      
2398             showWorkspace(true);                                                                         
2399         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2400             Folder openFolder = mWorkspace.getOpenFolder();                                              
2401             if (openFolder.isEditingName()) {                                                            
2402                 openFolder.dismissEditingName();                                                         
2403             } else {                                                                                     
2404                 closeFolder();                                                                           
2405             }                                                                                            
2406         } else {                                                                                         
2407             mWorkspace.exitWidgetResizeMode();                                                           
2408             // Back button is a no-op here, but give at least some feedback for the button press         
2409             mWorkspace.showOutlinesTemporarily();                                                        
2410         }                                                                                                
2411     }                                                                                                    
2412                                                                                                          
2413     /**                                                                                                  
2414      * Re-listen when widgets are reset.                                                                 
2415      */                                                                                                  
2416     @Thunk                                                                                               
2417     void onAppWidgetReset() {                                                                            
2418         if (mAppWidgetHost != null) {                                                                    
2419             mAppWidgetHost.startListening();                                                             
2420         }                                                                                                
2421     }                                                                                                    
2422                                                                                                          
2423     /**                                                                                                  
2424      * Launches the intent referred by the clicked shortcut.                                             
2425      *                                                                                                   
2426      * @param v The view representing the clicked shortcut.                                              
2427      */                                                                                                  
2428     public void onClick(View v) {                                                                        
2429         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2430         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2431         if (v.getWindowToken() == null) {                                                                
2432             return;                                                                                      
2433         }                                                                                                
2434         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2435             return;                                                                                      
2436         }                                                                                                
2437         if (v instanceof Workspace) {                                                                    
2438             if (mWorkspace.isInOverviewMode()) {                                                         
2439                 showWorkspace(true);                                                                     
2440             }                                                                                            
2441             return;                                                                                      
2442         }                                                                                                
2443         if (v instanceof CellLayout) {                                                                   
2444             if (mWorkspace.isInOverviewMode()) {                                                         
2445                 showWorkspace(mWorkspace.indexOfChild(v), true);                                         
2446             }                                                                                            
2447         }                                                                                                
2448         Object tag = v.getTag();                                                                         
2449         if (tag instanceof ShortcutInfo) {                                                               
2450             onClickAppShortcut(v);                                                                       
2451         } else if (tag instanceof FolderInfo) {                                                          
2452             if (v instanceof FolderIcon) {                                                               
2453                 onClickFolderIcon(v);                                                                    
2454             }                                                                                            
2455         } else if (v == mAllAppsButton) {                                                                
2456             onClickAllAppsButton(v);                                                                     
2457         } else if (tag instanceof AppInfo) {                                                             
2458             startAppShortcutOrInfoActivity(v);                                                           
2459         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2460             if (v instanceof PendingAppWidgetHostView) {                                                 
2461                 onClickPendingWidget(((PendingAppWidgetHostView) (v)));                                  
2462             }                                                                                            
2463         }                                                                                                
2464     }                                                                                                    
2465                                                                                                          
2466     public void onClickPagedViewIcon(View v) {                                                           
2467         startAppShortcutOrInfoActivity(v);                                                               
2468         if (mLauncherCallbacks != null) {                                                                
2469             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2470         }                                                                                                
2471     }                                                                                                    
2472                                                                                                          
2473     @SuppressLint("ClickableViewAccessibility")                                                          
2474     public boolean onTouch(View v, MotionEvent event) {                                                  
2475         return false;                                                                                    
2476     }                                                                                                    
2477                                                                                                          
2478     /**                                                                                                  
2479      * Event handler for the app widget view which has not fully restored.                               
2480      */                                                                                                  
2481     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2482         if (mIsSafeModeEnabled) {                                                                        
2483             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2484             return;                                                                                      
2485         }                                                                                                
2486                                                                                                          
2487         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2488         if (v.isReadyForClickSetup()) {                                                                  
2489             int widgetId = info.appWidgetId;                                                             
2490             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2491             if (appWidgetInfo != null) {                                                                 
2492                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2493                         this, appWidgetInfo);                                                            
2494                 mPendingAddInfo.copyFrom(info);                                                          
2495                 mPendingAddWidgetId = widgetId;                                                          
2496                                                                                                          
2497                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2498                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2499             }                                                                                            
2500         } else if (info.installProgress < 0) {                                                           
2501             // The install has not been queued                                                           
2502             final String packageName = info.providerName.getPackageName();                               
2503             showBrokenAppInstallDialog(packageName,                                                      
2504                 new DialogInterface.OnClickListener() {                                                  
2505                     public void onClick(DialogInterface dialog, int id) {                                
2506                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2507                     }                                                                                    
2508                 });                                                                                      
2509         } else {                                                                                         
2510             // Download has started.                                                                     
2511             final String packageName = info.providerName.getPackageName();                               
2512             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2513         }                                                                                                
2514     }                                                                                                    
2515                                                                                                          
2516     /**                                                                                                  
2517      * Event handler for the "grid" button that appears on the home screen, which                        
2518      * enters all apps mode.                                                                             
2519      *                                                                                                   
2520      * @param v The view that was clicked.                                                               
2521      */                                                                                                  
2522     protected void onClickAllAppsButton(View v) {                                                        
2523         if (LOGD) {                                                                                      
2524             Log.d(TAG, "onClickAllAppsButton");                                                          
2525         }                                                                                                
2526         if (isAppsViewVisible()) {                                                                       
2527             showWorkspace(true);                                                                         
2528         } else {                                                                                         
2529             // Try and refresh the set of predicted apps before we enter launcher                        
2530             /* animated */                                                                               
2531             /* resetListToTop */                                                                         
2532             /* updatePredictedApps */                                                                    
2533             showAppsView(true, false, true);                                                             
2534         }                                                                                                
2535     }                                                                                                    
2536                                                                                                          
2537     private void showBrokenAppInstallDialog(final String packageName,                                    
2538             DialogInterface.OnClickListener onSearchClickListener) {                                     
2539         new AlertDialog.Builder(this)                                                                    
2540             .setTitle(R.string.abandoned_promises_title)                                                 
2541             .setMessage(R.string.abandoned_promise_explanation)                                          
2542             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2543             .setNeutralButton(R.string.abandoned_clean_this,                                             
2544                 new DialogInterface.OnClickListener() {                                                  
2545                     public void onClick(DialogInterface dialog, int id) {                                
2546                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2547                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2548                     }                                                                                    
2549                 })                                                                                       
2550             .create().show();                                                                            
2551         return;                                                                                          
2552     }                                                                                                    
2553                                                                                                          
2554     /**                                                                                                  
2555      * Event handler for an app shortcut click.                                                          
2556      *                                                                                                   
2557      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2558      */                                                                                                  
2559     protected void onClickAppShortcut(final View v) {                                                    
2560         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2561         Object tag = v.getTag();                                                                         
2562         if (!(tag instanceof ShortcutInfo)) {                                                            
2563             throw new IllegalArgumentException("Input must be a Shortcut");                              
2564         }                                                                                                
2565                                                                                                          
2566         // Open shortcut                                                                                 
2567         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2568                                                                                                          
2569         if (shortcut.isDisabled != 0) {                                                                  
2570             int error = R.string.activity_not_available;                                                 
2571             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2572                 error = R.string.safemode_shortcut_error;                                                
2573             }                                                                                            
2574             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2575             return;                                                                                      
2576         }                                                                                                
2577                                                                                                          
2578         final Intent intent = shortcut.intent;                                                           
2579                                                                                                          
2580         // Check for special shortcuts                                                                   
2581         if (intent.getComponent() != null) {                                                             
2582             final String shortcutClass = intent.getComponent().getClassName();                           
2583                                                                                                          
2584             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2585                 MemoryDumpActivity.startDump(this);                                                      
2586                 return;                                                                                  
2587             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2588                 toggleShowWeightWatcher();                                                               
2589                 return;                                                                                  
2590             }                                                                                            
2591         }                                                                                                
2592                                                                                                          
2593         // Check for abandoned promise                                                                   
2594         if ((v instanceof BubbleTextView)                                                                
2595                 && shortcut.isPromise()                                                                  
2596                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2597             showBrokenAppInstallDialog(                                                                  
2598                     shortcut.getTargetComponent().getPackageName(),                                      
2599                     new DialogInterface.OnClickListener() {                                              
2600                         public void onClick(DialogInterface dialog, int id) {                            
2601                             startAppShortcutOrInfoActivity(v);                                           
2602                         }                                                                                
2603                     });                                                                                  
2604             return;                                                                                      
2605         }                                                                                                
2606                                                                                                          
2607         // Start activities                                                                              
2608         startAppShortcutOrInfoActivity(v);                                                               
2609                                                                                                          
2610         if (mLauncherCallbacks != null) {                                                                
2611             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2612         }                                                                                                
2613     }                                                                                                    
2614                                                                                                          
2615     @Thunk                                                                                               
2616     void startAppShortcutOrInfoActivity(View v) {                                                        
2617         Object tag = v.getTag();                                                                         
2618         final ShortcutInfo shortcut;                                                                     
2619         final Intent intent;                                                                             
2620         if (tag instanceof ShortcutInfo) {                                                               
2621             shortcut = ((ShortcutInfo) (tag));                                                           
2622             intent = shortcut.intent;                                                                    
2623             int[] pos = new int[2];                                                                      
2624             v.getLocationOnScreen(pos);                                                                  
2625             intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight()🔵
2626         } else if (tag instanceof AppInfo) {                                                             
2627             shortcut = null;                                                                             
2628             intent = ((AppInfo) (tag)).intent;                                                           
2629         } else {                                                                                         
2630             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2631         }                                                                                                
2632         boolean success = startActivitySafely(v, intent, tag);                                           
2633         mStats.recordLaunch(intent, shortcut);                                                           
2634         if (success && (v instanceof BubbleTextView)) {                                                  
2635             mWaitingForResume = ((BubbleTextView) (v));                                                  
2636             mWaitingForResume.setStayPressed(true);                                                      
2637         }                                                                                                
2638     }                                                                                                    
2639                                                                                                          
2640     /**                                                                                                  
2641      * Event handler for a folder icon click.                                                            
2642      *                                                                                                   
2643      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2644      */                                                                                                  
2645     protected void onClickFolderIcon(View v) {                                                           
2646         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2647         if (!(v instanceof FolderIcon)){                                                                 
2648             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2649         }                                                                                                
2650                                                                                                          
2651         FolderIcon folderIcon = (FolderIcon) v;                                                          
2652         final FolderInfo info = folderIcon.getFolderInfo();                                              
2653         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2654                                                                                                          
2655         // If the folder info reports that the associated folder is open, then verify that               
2656         // it is actually opened. There have been a few instances where this gets out of sync.           
2657         if (info.opened && openFolder == null) {                                                         
2658             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2659                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2660             info.opened = false;                                                                         
2661         }                                                                                                
2662                                                                                                          
2663         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2664             // Close any open folder                                                                     
2665             closeFolder();                                                                               
2666             // Open the requested folder                                                                 
2667             openFolder(folderIcon);                                                                      
2668         } else {                                                                                         
2669             // Find the open folder...                                                                   
2670             int folderScreen;                                                                            
2671             if (openFolder != null) {                                                                    
2672                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2673                 // .. and close it                                                                       
2674                 closeFolder(openFolder);                                                                 
2675                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2676                     // Close any folder open on the current screen                                       
2677                     closeFolder();                                                                       
2678                     // Pull the folder onto this screen                                                  
2679                     openFolder(folderIcon);                                                              
2680                 }                                                                                        
2681             }                                                                                            
2682         }                                                                                                
2683                                                                                                          
2684         if (mLauncherCallbacks != null) {                                                                
2685             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2686         }                                                                                                
2687     }                                                                                                    
2688                                                                                                          
2689     /**                                                                                                  
2690      * Event handler for the (Add) Widgets button that appears after a long press                        
2691      * on the home screen.                                                                               
2692      */                                                                                                  
2693     protected void onClickAddWidgetButton(View view) {                                                   
2694         if (LOGD) {                                                                                      
2695             Log.d(TAG, "onClickAddWidgetButton");                                                        
2696         }                                                                                                
2697         if (mIsSafeModeEnabled) {                                                                        
2698             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2699         } else {                                                                                         
2700             /* animated */                                                                               
2701             /* resetPageToZero */                                                                        
2702             showWidgetsView(true, true);                                                                 
2703             if (mLauncherCallbacks != null) {                                                            
2704                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2705             }                                                                                            
2706         }                                                                                                
2707     }                                                                                                    
2708                                                                                                          
2709     /**                                                                                                  
2710      * Event handler for the wallpaper picker button that appears after a long press                     
2711      * on the home screen.                                                                               
2712      */                                                                                                  
2713     protected void onClickWallpaperPicker(View v) {                                                      
2714         if (LOGD) {                                                                                      
2715             Log.d(TAG, "onClickWallpaperPicker");                                                        
2716         }                                                                                                
2717         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()), REQU🔵
2718         if (mLauncherCallbacks != null) {                                                                
2719             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2720         }                                                                                                
2721     }                                                                                                    
2722                                                                                                          
2723     /**                                                                                                  
2724      * Event handler for a click on the settings button that appears after a long press                  
2725      * on the home screen.                                                                               
2726      */                                                                                                  
2727     protected void onClickSettingsButton(View v) {                                                       
2728         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2729         if (mLauncherCallbacks != null) {                                                                
2730             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2731         }                                                                                                
2732     }                                                                                                    
2733                                                                                                          
2734     public void onTouchDownAllAppsButton(View v) {                                                       
2735         // Provide the same haptic feedback that the system offers for virtual keys.                     
2736         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2737     }                                                                                                    
2738                                                                                                          
2739     public void performHapticFeedbackOnTouchDown(View v) {                                               
2740         // Provide the same haptic feedback that the system offers for virtual keys.                     
2741         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2742     }                                                                                                    
2743                                                                                                          
2744     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2745         if (mHapticFeedbackTouchListener == null) {                                                      
2746             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2747                 @SuppressLint("ClickableViewAccessibility")                                              
2748                 @Override                                                                                
2749                 public boolean onTouch(View v, MotionEvent event) {                                      
2750                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2751                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2752                     }                                                                                    
2753                     return false;                                                                        
2754                 }                                                                                        
2755             };                                                                                           
2756         }                                                                                                
2757         return mHapticFeedbackTouchListener;                                                             
2758     }                                                                                                    
2759                                                                                                          
2760     public void onDragStarted(View view) {                                                               
2761         if (isOnCustomContent()) {                                                                       
2762             // Custom content screen doesn't participate in drag and drop. If on custom                  
2763             // content screen, move to default.                                                          
2764             moveWorkspaceToDefaultScreen();                                                              
2765         }                                                                                                
2766                                                                                                          
2767         if (mLauncherCallbacks != null) {                                                                
2768             mLauncherCallbacks.onDragStarted(view);                                                      
2769         }                                                                                                
2770     }                                                                                                    
2771                                                                                                          
2772     /**                                                                                                  
2773      * Called when the user stops interacting with the launcher.                                         
2774      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2775      */                                                                                                  
2776     protected void onInteractionEnd() {                                                                  
2777         if (mLauncherCallbacks != null) {                                                                
2778             mLauncherCallbacks.onInteractionEnd();                                                       
2779         }                                                                                                
2780     }                                                                                                    
2781                                                                                                          
2782     /**                                                                                                  
2783      * Called when the user starts interacting with the launcher.                                        
2784      * The possible interactions are:                                                                    
2785      *  - open all apps                                                                                  
2786      *  - reorder an app shortcut, or a widget                                                           
2787      *  - open the overview mode.                                                                        
2788      * This is a good time to stop doing things that only make sense                                     
2789      * when the user is on the homescreen and not doing housekeeping.                                    
2790      */                                                                                                  
2791     protected void onInteractionBegin() {                                                                
2792         if (mLauncherCallbacks != null) {                                                                
2793             mLauncherCallbacks.onInteractionBegin();                                                     
2794         }                                                                                                
2795     }                                                                                                    
2796                                                                                                          
2797     /** Updates the interaction state. */                                                                
2798     public void updateInteraction(Workspace.State fromState, Workspace.State toState) {                  
2799         // Only update the interacting state if we are transitioning to/from a view with an              
2800         // overlay                                                                                       
2801         boolean fromStateWithOverlay;                                                                    
2802         boolean toStateWithOverlay;                                                                      
2803         if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                              
2804             fromStateWithOverlay = fromState != Workspace.State.NORMAL;                                  
2805             toStateWithOverlay = toState != Workspace.State.NORMAL;                                      
2806         } else {                                                                                         
2807             fromStateWithOverlay = (fromState != Workspace.State.NORMAL) && (fromState != Workspace.State🔵
2808             toStateWithOverlay = (toState != Workspace.State.NORMAL) && (toState != Workspace.State.NORMA🔵
2809         }                                                                                                
2810         if (toStateWithOverlay) {                                                                        
2811             onInteractionBegin();                                                                        
2812         } else if (fromStateWithOverlay) {                                                               
2813             onInteractionEnd();                                                                          
2814         }                                                                                                
2815     }                                                                                                    
2816                                                                                                          
2817     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2818         try {                                                                                            
2819             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2820             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2821         } catch (SecurityException e) {                                                                  
2822             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2823             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2824         } catch (ActivityNotFoundException e) {                                                          
2825             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2826             Log.e(TAG, "Unable to launch settings");                                                     
2827         }                                                                                                
2828     }                                                                                                    
2829                                                                                                          
2830     // returns true if the activity was started                                                          
2831     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2832             UserHandleCompat user) {                                                                     
2833         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2834             // System applications cannot be installed. For now, show a toast explaining that.           
2835             // We may give them the option of disabling apps this way.                                   
2836             int messageId = R.string.uninstall_system_app_text;                                          
2837             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2838             return false;                                                                                
2839         } else {                                                                                         
2840             String packageName = componentName.getPackageName();                                         
2841             String className = componentName.getClassName();                                             
2842             Intent intent = new Intent(                                                                  
2843                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2844             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2845                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2846             if (user != null) {                                                                          
2847                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2848             }                                                                                            
2849             startActivity(intent);                                                                       
2850             return true;                                                                                 
2851         }                                                                                                
2852     }                                                                                                    
2853                                                                                                          
2854     boolean startActivity(View v, Intent intent, Object tag) {                                           
2855         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2856         try {                                                                                            
2857             // Only launch using the new animation if the shortcut has not opted out (this is a          
2858             // private contract between launcher and may be ignored in the future).                      
2859             boolean useLaunchAnimation = (v != null) && (!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIM🔵
2860             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2861             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2862             UserHandleCompat user = null;                                                                
2863             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2864                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2865                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2866             }                                                                                            
2867             Bundle optsBundle = null;                                                                    
2868             if (useLaunchAnimation) {                                                                    
2869                 ActivityOptions opts = null;                                                             
2870                 if (sClipRevealMethod != null) {                                                         
2871                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2872                     int left = 0;                                                                        
2873                     int top = 0;                                                                         
2874                     int width = v.getMeasuredWidth();                                                    
2875                     int height = v.getMeasuredHeight();                                                  
2876                     if (v instanceof TextView) {                                                         
2877                         // Launch from center of icon, not entire view                                   
2878                         Drawable icon = Workspace.getTextViewIcon(((TextView) (v)));                     
2879                         if (icon != null) {                                                              
2880                             Rect bounds = icon.getBounds();                                              
2881                             left = (width - bounds.width()) / 2;                                         
2882                             top = v.getPaddingTop();                                                     
2883                             width = bounds.width();                                                      
2884                             height = bounds.height();                                                    
2885                         }                                                                                
2886                     }                                                                                    
2887                     try {                                                                                
2888                         opts = ((ActivityOptions) (sClipRevealMethod.invoke(null, v, left, top, width, he🔵
2889                     } catch (java.lang.IllegalAccessException e) {                                       
2890                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2891                         sClipRevealMethod = null;                                                        
2892                     } catch (InvocationTargetException e) {                                              
2893                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2894                         sClipRevealMethod = null;                                                        
2895                     }                                                                                    
2896                 }                                                                                        
2897                 if ((opts == null) && (!Utilities.isLmpOrAbove())) {                                     
2898                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasu🔵
2899                 }                                                                                        
2900                 optsBundle = (opts != null) ? opts.toBundle() : null;                                    
2901             }                                                                                            
2902             if ((user == null) || user.equals(UserHandleCompat.myUserHandle())) {                        
2903                 // Could be launching some bookkeeping activity                                          
2904                 startActivity(intent, optsBundle);                                                       
2905             } else {                                                                                     
2906                 // TODO Component can be null when shortcuts are supported for secondary user            
2907                 launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(🔵
2908             }                                                                                            
2909             return true;                                                                                 
2910         } catch (java.lang.SecurityException e) {                                                        
2911             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2912             Log.e(TAG, (((((("Launcher does not have the permission to launch " + intent) + ". Make sure 🔵
2913         }                                                                                                
2914         return false;                                                                                    
2915     }                                                                                                    
2916                                                                                                          
2917     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2918         boolean success = false;                                                                         
2919         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2920             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2921             return false;                                                                                
2922         }                                                                                                
2923         try {                                                                                            
2924             success = startActivity(v, intent, tag);                                                     
2925         } catch (ActivityNotFoundException e) {                                                          
2926             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2927             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2928         }                                                                                                
2929         return success;                                                                                  
2930     }                                                                                                    
2931                                                                                                          
2932     /**                                                                                                  
2933      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2934      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2935      */                                                                                                  
2936     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2937         final int width = fi.getMeasuredWidth();                                                         
2938         final int height = fi.getMeasuredHeight();                                                       
2939                                                                                                          
2940         // Lazy load ImageView, Bitmap and Canvas                                                        
2941         if (mFolderIconImageView == null) {                                                              
2942             mFolderIconImageView = new ImageView(this);                                                  
2943         }                                                                                                
2944         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2945                 mFolderIconBitmap.getHeight() != height) {                                               
2946             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2947             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2948         }                                                                                                
2949                                                                                                          
2950         DragLayer.LayoutParams lp;                                                                       
2951         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2952             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2953         } else {                                                                                         
2954             lp = new DragLayer.LayoutParams(width, height);                                              
2955         }                                                                                                
2956                                                                                                          
2957         // The layout from which the folder is being opened may be scaled, adjust the starting           
2958         // view size by this scale factor.                                                               
2959         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2960         lp.customPosition = true;                                                                        
2961         lp.x = mRectForFolderAnimation.left;                                                             
2962         lp.y = mRectForFolderAnimation.top;                                                              
2963         lp.width = (int) (scale * width);                                                                
2964         lp.height = (int) (scale * height);                                                              
2965                                                                                                          
2966         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2967         fi.draw(mFolderIconCanvas);                                                                      
2968         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2969         if (fi.getFolder() != null) {                                                                    
2970             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2971             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2972         }                                                                                                
2973         // Just in case this image view is still in the drag layer from a previous animation,            
2974         // we remove it and re-add it.                                                                   
2975         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
2976             mDragLayer.removeView(mFolderIconImageView);                                                 
2977         }                                                                                                
2978         mDragLayer.addView(mFolderIconImageView, lp);                                                    
2979         if (fi.getFolder() != null) {                                                                    
2980             fi.getFolder().bringToFront();                                                               
2981         }                                                                                                
2982     }                                                                                                    
2983                                                                                                          
2984     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
2985         if (fi == null) return;                                                                          
2986         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
2987         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
2988         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
2989                                                                                                          
2990         FolderInfo info = (FolderInfo) fi.getTag();                                                      
2991         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
2992             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
2993             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
2994             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
2995         }                                                                                                
2996                                                                                                          
2997         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
2998         copyFolderIconToImage(fi);                                                                       
2999         fi.setVisibility(View.INVISIBLE);                                                                
3000                                                                                                          
3001         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3002                 scaleX, scaleY);                                                                         
3003         if (Utilities.isLmpOrAbove()) {                                                                  
3004             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3005         }                                                                                                
3006         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3007         oa.start();                                                                                      
3008     }                                                                                                    
3009                                                                                                          
3010     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3011         if (fi == null) return;                                                                          
3012         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3013         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3014         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3015                                                                                                          
3016         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3017                                                                                                          
3018         // We remove and re-draw the FolderIcon in-case it has changed                                   
3019         mDragLayer.removeView(mFolderIconImageView);                                                     
3020         copyFolderIconToImage(fi);                                                                       
3021         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3022                 scaleX, scaleY);                                                                         
3023         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3024         oa.addListener(new AnimatorListenerAdapter() {                                                   
3025             @Override                                                                                    
3026             public void onAnimationEnd(Animator animation) {                                             
3027                 if (cl != null) {                                                                        
3028                     cl.clearFolderLeaveBehind();                                                         
3029                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3030                     mDragLayer.removeView(mFolderIconImageView);                                         
3031                     fi.setVisibility(View.VISIBLE);                                                      
3032                 }                                                                                        
3033             }                                                                                            
3034         });                                                                                              
3035         oa.start();                                                                                      
3036     }                                                                                                    
3037                                                                                                          
3038     /**                                                                                                  
3039      * Opens the user folder described by the specified tag. The opening of the folder                   
3040      * is animated relative to the specified View. If the View is null, no animation                     
3041      * is played.                                                                                        
3042      *                                                                                                   
3043      * @param folderInfo The FolderInfo describing the folder to open.                                   
3044      */                                                                                                  
3045     public void openFolder(FolderIcon folderIcon) {                                                      
3046         Folder folder = folderIcon.getFolder();                                                          
3047         Folder openFolder = (mWorkspace != null) ? mWorkspace.getOpenFolder() : null;                    
3048         if ((openFolder != null) && (openFolder != folder)) {                                            
3049             // Close any open folder before opening a folder.                                            
3050             closeFolder();                                                                               
3051         }                                                                                                
3052         FolderInfo info = folder.mInfo;                                                                  
3053         info.opened = true;                                                                              
3054         // While the folder is open, the position of the icon cannot change.                             
3055         ((CellLayout.LayoutParams) (folderIcon.getLayoutParams())).canReorder = false;                   
3056         // Just verify that the folder hasn't already been added to the DragLayer.                       
3057         // There was a one-off crash where the folder had a parent already.                              
3058         if (folder.getParent() == null) {                                                                
3059             mDragLayer.addView(folder);                                                                  
3060             mDragController.addDropTarget(((DropTarget) (folder)));                                      
3061         } else {                                                                                         
3062             Log.w(TAG, ((("Opening folder (" + folder) + ") which already has a parent (") + folder.getPa🔵
3063         }                                                                                                
3064         folder.animateOpen();                                                                            
3065         growAndFadeOutFolderIcon(folderIcon);                                                            
3066         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3067         // the workspace items                                                                           
3068         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3069         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3070     }                                                                                                    
3071                                                                                                          
3072     public void closeFolder() {                                                                          
3073         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3074         if (folder != null) {                                                                            
3075             if (folder.isEditingName()) {                                                                
3076                 folder.dismissEditingName();                                                             
3077             }                                                                                            
3078             closeFolder(folder);                                                                         
3079         }                                                                                                
3080     }                                                                                                    
3081                                                                                                          
3082     public void closeFolder(Folder folder) {                                                             
3083         folder.getInfo().opened = false;                                                                 
3084         ViewGroup parent = ((ViewGroup) (folder.getParent().getParent()));                               
3085         if (parent != null) {                                                                            
3086             FolderIcon fi = ((FolderIcon) (mWorkspace.getViewForTag(folder.mInfo)));                     
3087             shrinkAndFadeInFolderIcon(fi);                                                               
3088             if (fi != null) {                                                                            
3089                 ((CellLayout.LayoutParams) (fi.getLayoutParams())).canReorder = true;                    
3090             }                                                                                            
3091         }                                                                                                
3092         folder.animateClosed();                                                                          
3093         // Notify the accessibility manager that this folder "window" has disappeard and no              
3094         // longer occludeds the workspace items                                                          
3095         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3096     }                                                                                                    
3097                                                                                                          
3098     public boolean onLongClick(View v) {                                                                 
3099         if (!isDraggingEnabled()) {                                                                      
3100             return false;                                                                                
3101         }                                                                                                
3102         if (isWorkspaceLocked()) {                                                                       
3103             return false;                                                                                
3104         }                                                                                                
3105         if (mState != State.WORKSPACE) {                                                                 
3106             return false;                                                                                
3107         }                                                                                                
3108         if (v instanceof Workspace) {                                                                    
3109             if (!mWorkspace.isInOverviewMode()) {                                                        
3110                 if (!mWorkspace.isTouchActive()) {                                                       
3111                     showOverviewMode(true);                                                              
3112                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackCo🔵
3113                     return true;                                                                         
3114                 } else {                                                                                 
3115                     return false;                                                                        
3116                 }                                                                                        
3117             } else {                                                                                     
3118                 return false;                                                                            
3119             }                                                                                            
3120         }                                                                                                
3121         CellLayout.CellInfo longClickCellInfo = null;                                                    
3122         View itemUnderLongClick = null;                                                                  
3123         if (v.getTag() instanceof ItemInfo) {                                                            
3124             ItemInfo info = ((ItemInfo) (v.getTag()));                                                   
3125             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3126             itemUnderLongClick = longClickCellInfo.cell;                                                 
3127             resetAddInfo();                                                                              
3128         }                                                                                                
3129         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3130         // on hotseat items.                                                                             
3131         final boolean inHotseat = isHotseatLayout(v);                                                    
3132         if (!mDragController.isDragging()) {                                                             
3133             if (itemUnderLongClick == null) {                                                            
3134                 // User long pressed on empty space                                                      
3135                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConsta🔵
3136                 if (mWorkspace.isInOverviewMode()) {                                                     
3137                     mWorkspace.startReordering(v);                                                       
3138                 } else {                                                                                 
3139                     showOverviewMode(true);                                                              
3140                 }                                                                                        
3141             } else {                                                                                     
3142                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(mHotseat.getOrderInHotse🔵
3143                 if (!((itemUnderLongClick instanceof Folder) || isAllAppsButton)) {                      
3144                     // User long pressed on an item                                                      
3145                     mWorkspace.startDrag(longClickCellInfo);                                             
3146                 }                                                                                        
3147             }                                                                                            
3148         }                                                                                                
3149         return true;                                                                                     
3150     }                                                                                                    
3151                                                                                                          
3152     boolean isHotseatLayout(View layout) {                                                               
3153         return mHotseat != null && layout != null &&                                                     
3154                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3155     }                                                                                                    
3156                                                                                                          
3157     /**                                                                                                  
3158      * Returns the CellLayout of the specified container at the specified screen.                        
3159      */                                                                                                  
3160     public CellLayout getCellLayout(long container, long screenId) {                                     
3161         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3162             if (mHotseat != null) {                                                                      
3163                 return mHotseat.getLayout();                                                             
3164             } else {                                                                                     
3165                 return null;                                                                             
3166             }                                                                                            
3167         } else {                                                                                         
3168             return mWorkspace.getScreenWithId(screenId);                                                 
3169         }                                                                                                
3170     }                                                                                                    
3171                                                                                                          
3172     /**                                                                                                  
3173      * For overridden classes.                                                                           
3174      */                                                                                                  
3175     public boolean isAllAppsVisible() {                                                                  
3176         return isAppsViewVisible();                                                                      
3177     }                                                                                                    
3178                                                                                                          
3179     public boolean isAppsViewVisible() {                                                                 
3180         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3181     }                                                                                                    
3182                                                                                                          
3183     public boolean isWidgetsViewVisible() {                                                              
3184         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3185     }                                                                                                    
3186                                                                                                          
3187     private void setWorkspaceBackground(int background) {                                                
3188         switch (background) {                                                                            
3189             case WORKSPACE_BACKGROUND_TRANSPARENT :                                                      
3190                 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));                 
3191                 break;                                                                                   
3192             case WORKSPACE_BACKGROUND_BLACK :                                                            
3193                 getWindow().setBackgroundDrawable(null);                                                 
3194                 break;                                                                                   
3195             default :                                                                                    
3196                 getWindow().setBackgroundDrawable(mWorkspaceBackgroundDrawable);                         
3197         }                                                                                                
3198     }                                                                                                    
3199                                                                                                          
3200     protected void changeWallpaperVisiblity(boolean visible) {                                           
3201         int wpflags = (visible) ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                    
3202         int curflags = getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER🔵
3203         if (wpflags != curflags) {                                                                       
3204             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3205         }                                                                                                
3206         setWorkspaceBackground(visible ? WORKSPACE_BACKGROUND_GRADIENT : WORKSPACE_BACKGROUND_BLACK);    
3207     }                                                                                                    
3208                                                                                                          
3209     @Override                                                                                            
3210     public void onTrimMemory(int level) {                                                                
3211         super.onTrimMemory(level);                                                                       
3212         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3213             // The widget preview db can result in holding onto over                                     
3214             // 3MB of memory for caching which isn't necessary.                                          
3215             SQLiteDatabase.releaseMemory();                                                              
3216             // This clears all widget bitmaps from the widget tray                                       
3217             // TODO(hyunyoungs)                                                                          
3218         }                                                                                                
3219         if (mLauncherCallbacks != null) {                                                                
3220             mLauncherCallbacks.onTrimMemory(level);                                                      
3221         }                                                                                                
3222     }                                                                                                    
3223                                                                                                          
3224     @Override                                                                                            
3225     public void onStateTransitionHideSearchBar() {                                                       
3226         // Hide the search bar                                                                           
3227         if (mSearchDropTargetBar != null) {                                                              
3228             /* animated */                                                                               
3229             mSearchDropTargetBar.hideSearchBar(false);                                                   
3230         }                                                                                                
3231     }                                                                                                    
3232                                                                                                          
3233     public void showWorkspace(boolean animated) {                                                        
3234         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null, true);   
3235     }                                                                                                    
3236                                                                                                          
3237     public void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                           
3238         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, onCompleteRunna🔵
3239     }                                                                                                    
3240                                                                                                          
3241     protected void showWorkspace(int snapToPage, boolean animated) {                                     
3242         showWorkspace(snapToPage, animated, null, true);                                                 
3243     }                                                                                                    
3244                                                                                                          
3245     void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable, boolean notifyLaunc🔵
3246         boolean changed = (mState != State.WORKSPACE) || (mWorkspace.getState() != Workspace.State.NORMAL🔵
3247         if (changed) {                                                                                   
3248             boolean wasInSpringLoadedMode = mState != State.WORKSPACE;                                   
3249             mWorkspace.setVisibility(View.VISIBLE);                                                      
3250             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL, snapToPag🔵
3251             // Show the search bar (only animate if we were showing the drop target bar in spring        
3252             // loaded mode)                                                                              
3253             if (mSearchDropTargetBar != null) {                                                          
3254                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3255             }                                                                                            
3256             // Set focus to the AppsCustomize button                                                     
3257             if (mAllAppsButton != null) {                                                                
3258                 mAllAppsButton.requestFocus();                                                           
3259             }                                                                                            
3260         }                                                                                                
3261         // Change the state *after* we've called all the transition code                                 
3262         mState = State.WORKSPACE;                                                                        
3263         // Resume the auto-advance of widgets                                                            
3264         mUserPresent = true;                                                                             
3265         updateAutoAdvanceState();                                                                        
3266         if (changed) {                                                                                   
3267             // Send an accessibility event to announce the context change                                
3268             getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGE🔵
3269             if (notifyLauncherCallbacks) {                                                               
3270                 // Dismiss all apps when the workspace is shown                                          
3271                 if ((!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) && (mLauncherCallbacks != null)) {   
3272                     mLauncherCallbacks.onAllAppsHidden();                                                
3273                 }                                                                                        
3274             }                                                                                            
3275         }                                                                                                
3276     }                                                                                                    
3277                                                                                                          
3278     void showOverviewMode(boolean animated) {                                                            
3279         mWorkspace.setVisibility(View.VISIBLE);                                                          
3280         /* onCompleteRunnable */                                                                         
3281         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW, WorkspaceSt🔵
3282         mState = State.WORKSPACE;                                                                        
3283     }                                                                                                    
3284                                                                                                          
3285     /**                                                                                                  
3286      * Shows the apps view.                                                                              
3287      */                                                                                                  
3288     void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps) {           
3289         if (resetListToTop) {                                                                            
3290             mAppsView.scrollToTop();                                                                     
3291         }                                                                                                
3292         if (updatePredictedApps) {                                                                       
3293             tryAndUpdatePredictedApps();                                                                 
3294         }                                                                                                
3295         showAppsOrWidgets(animated, State.APPS);                                                         
3296     }                                                                                                    
3297                                                                                                          
3298     /**                                                                                                  
3299      * Shows the widgets view.                                                                           
3300      */                                                                                                  
3301     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3302         if (LOGD) {                                                                                      
3303             Log.d(TAG, (("showWidgetsView:" + animated) + " resetPageToZero:") + resetPageToZero);       
3304         }                                                                                                
3305         if (resetPageToZero) {                                                                           
3306             mWidgetsView.scrollToTop();                                                                  
3307         }                                                                                                
3308         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3309         mWidgetsView.post(new Runnable() {                                                               
3310             @Override                                                                                    
3311             public void run() {                                                                          
3312                 mWidgetsView.requestFocus();                                                             
3313             }                                                                                            
3314         });                                                                                              
3315     }                                                                                                    
3316                                                                                                          
3317     /**                                                                                                  
3318      * Sets up the transition to show the apps/widgets view.                                             
3319      *                                                                                                   
3320      * @return whether the current from and to state allowed this operation                              
3321      */                                                                                                  
3322     // TODO: calling method should use the return value so that when {@code false} is returned           
3323     // the workspace transition doesn't fall into invalid state.                                         
3324     private boolean showAppsOrWidgets(boolean animated, State toState) {                                 
3325         if (((mState != State.WORKSPACE) && (mState != State.APPS_SPRING_LOADED)) && (mState != State.WID🔵
3326             return false;                                                                                
3327         }                                                                                                
3328         if ((toState != State.APPS) && (toState != State.WIDGETS)) {                                     
3329             return false;                                                                                
3330         }                                                                                                
3331         if (toState == State.APPS) {                                                                     
3332             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3333             if ((!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) && (mLauncherCallbacks != null)) {       
3334                 mLauncherCallbacks.onAllAppsShown();                                                     
3335             }                                                                                            
3336         } else {                                                                                         
3337             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3338         }                                                                                                
3339         // Change the state *after* we've called all the transition code                                 
3340         mState = toState;                                                                                
3341         // Pause the auto-advance of widgets until we are out of AllApps                                 
3342         mUserPresent = false;                                                                            
3343         updateAutoAdvanceState();                                                                        
3344         closeFolder();                                                                                   
3345         // Send an accessibility event to announce the context change                                    
3346         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3347         return true;                                                                                     
3348     }                                                                                                    
3349                                                                                                          
3350     /**                                                                                                  
3351      * Updates the workspace and interaction state on state change, and return the animation to this     
3352      * new state.                                                                                        
3353      */                                                                                                  
3354     public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, int toPage, boolean anima🔵
3355         Workspace.State fromState = mWorkspace.getState();                                               
3356         Animator anim = mWorkspace.setStateWithAnimation(toState, toPage, animated, layerViews);         
3357         updateInteraction(fromState, toState);                                                           
3358         return anim;                                                                                     
3359     }                                                                                                    
3360                                                                                                          
3361     public void enterSpringLoadedDragMode() {                                                            
3362         if (LOGD) {                                                                                      
3363             Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", mState.name()));            
3364         }                                                                                                
3365         if (((mState == State.WORKSPACE) || (mState == State.APPS_SPRING_LOADED)) || (mState == State.WID🔵
3366             return;                                                                                      
3367         }                                                                                                
3368         /* animated */                                                                                   
3369         /* onCompleteRunnable */                                                                         
3370         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED, Worksp🔵
3371         mState = (isAppsViewVisible()) ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;         
3372     }                                                                                                    
3373                                                                                                          
3374     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay, final Runnable o🔵
3375         if ((mState != State.APPS_SPRING_LOADED) && (mState != State.WIDGETS_SPRING_LOADED)) {           
3376             return;                                                                                      
3377         }                                                                                                
3378         if (successfulDrop) {                                                                            
3379             // We need to trigger all apps hidden to notify search to update itself before the           
3380             // delayed call to showWorkspace below                                                       
3381             if ((!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) && (mLauncherCallbacks != null)) {       
3382                 mLauncherCallbacks.onAllAppsHidden();                                                    
3383             }                                                                                            
3384         }                                                                                                
3385         mHandler.postDelayed(new Runnable() {                                                            
3386             @Override                                                                                    
3387             public void run() {                                                                          
3388                 if (successfulDrop) {                                                                    
3389                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3390                     //                                                                                   
3391                     // Before we show workspace, hide all apps again because                             
3392                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3393                     // clean up our state transition functions                                           
3394                     mWidgetsView.setVisibility(View.GONE);                                               
3395                     showWorkspace(true, onCompleteRunnable);                                             
3396                 } else {                                                                                 
3397                     exitSpringLoadedDragMode();                                                          
3398                 }                                                                                        
3399             }                                                                                            
3400         }, delay);                                                                                       
3401     }                                                                                                    
3402                                                                                                          
3403     void exitSpringLoadedDragMode() {                                                                    
3404         if (mState == State.APPS_SPRING_LOADED) {                                                        
3405             /* animated */                                                                               
3406             /* resetListToTop */                                                                         
3407             /* updatePredictedApps */                                                                    
3408             showAppsView(true, false, false);                                                            
3409         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3410             showWidgetsView(true, false);                                                                
3411         }                                                                                                
3412     }                                                                                                    
3413                                                                                                          
3414     /**                                                                                                  
3415      * Updates the set of predicted apps if it hasn't been updated since the last time Launcher was      
3416      * resumed.                                                                                          
3417      */                                                                                                  
3418     private void tryAndUpdatePredictedApps() {                                                           
3419         if (mLauncherCallbacks != null) {                                                                
3420             List<ComponentName> apps = mLauncherCallbacks.getPredictedApps();                            
3421             if (!apps.isEmpty()) {                                                                       
3422                 mAppsView.setPredictedApps(apps);                                                        
3423             }                                                                                            
3424         }                                                                                                
3425     }                                                                                                    
3426                                                                                                          
3427     void lockAllApps() {                                                                                 
3428         // TODO                                                                                          
3429     }                                                                                                    
3430                                                                                                          
3431     void unlockAllApps() {                                                                               
3432         // TODO                                                                                          
3433     }                                                                                                    
3434                                                                                                          
3435     protected void disableVoiceButtonProxy(boolean disable) {                                            
3436         // NO-OP                                                                                         
3437     }                                                                                                    
3438                                                                                                          
3439     public View getOrCreateQsbBar() {                                                                    
3440         if ((mLauncherCallbacks != null) && mLauncherCallbacks.providesSearch()) {                       
3441             return mLauncherCallbacks.getQsbBar();                                                       
3442         }                                                                                                
3443         if (mQsb == null) {                                                                              
3444             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3445             if (searchProvider == null) {                                                                
3446                 return null;                                                                             
3447             }                                                                                            
3448             Bundle opts = new Bundle();                                                                  
3449             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, AppWidgetProviderInfo.WIDGET_CAT🔵
3450             SharedPreferences sp = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), MODE_🔵
3451             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3452             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3453             if (((!searchProvider.provider.flattenToString().equals(sp.getString(QSB_WIDGET_PROVIDER, nul🔵
3454                 // A valid widget is not already bound.                                                  
3455                 if (widgetId > (-1)) {                                                                   
3456                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3457                     widgetId = -1;                                                                       
3458                 }                                                                                        
3459                 // Try to bind a new widget                                                              
3460                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3461                 if (!AppWidgetManagerCompat.getInstance(this).bindAppWidgetIdIfAllowed(widgetId, searchPr🔵
3462                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3463                     widgetId = -1;                                                                       
3464                 }                                                                                        
3465                 sp.edit().putInt(QSB_WIDGET_ID, widgetId).putString(QSB_WIDGET_PROVIDER, searchProvider.p🔵
3466             }                                                                                            
3467             if (widgetId != (-1)) {                                                                      
3468                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3469                 mQsb.updateAppWidgetOptions(opts);                                                       
3470                 mQsb.setPadding(0, 0, 0, 0);                                                             
3471                 mSearchDropTargetBar.addView(mQsb);                                                      
3472                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3473             }                                                                                            
3474         }                                                                                                
3475         return mQsb;                                                                                     
3476     }                                                                                                    
3477                                                                                                          
3478     private void reinflateQSBIfNecessary() {                                                             
3479         if ((mQsb instanceof LauncherAppWidgetHostView) && ((LauncherAppWidgetHostView) (mQsb)).isReinfla🔵
3480             mSearchDropTargetBar.removeView(mQsb);                                                       
3481             mQsb = null;                                                                                 
3482             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3483         }                                                                                                
3484     }                                                                                                    
3485                                                                                                          
3486     @Override                                                                                            
3487     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3488         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3489         final List<CharSequence> text = event.getText();                                                 
3490         text.clear();                                                                                    
3491         // Populate event with a fake title based on the current state.                                  
3492         if (mState == State.APPS) {                                                                      
3493             text.add(getString(R.string.all_apps_button_label));                                         
3494         } else if (mState == State.WIDGETS) {                                                            
3495             text.add(getString(R.string.widget_button_text));                                            
3496         } else {                                                                                         
3497             text.add(getString(R.string.all_apps_home_button_label));                                    
3498         }                                                                                                
3499         return result;                                                                                   
3500     }                                                                                                    
3501                                                                                                          
3502     /**                                                                                                  
3503      * Receives notifications when system dialogs are to be closed.                                      
3504      */                                                                                                  
3505     @Thunk                                                                                               
3506     class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                   
3507         @Override                                                                                        
3508         public void onReceive(Context context, Intent intent) {                                          
3509             closeSystemDialogs();                                                                        
3510         }                                                                                                
3511     }                                                                                                    
3512                                                                                                          
3513     /**                                                                                                  
3514      * Receives notifications whenever the appwidgets are reset.                                         
3515      */                                                                                                  
3516     private class AppWidgetResetObserver extends ContentObserver {                                       
3517         public AppWidgetResetObserver() {                                                                
3518             super(new Handler());                                                                        
3519         }                                                                                                
3520                                                                                                          
3521         @Override                                                                                        
3522         public void onChange(boolean selfChange) {                                                       
3523             onAppWidgetReset();                                                                          
3524         }                                                                                                
3525     }                                                                                                    
3526                                                                                                          
3527     /**                                                                                                  
3528      * If the activity is currently paused, signal that we need to run the passed Runnable               
3529      * in onResume.                                                                                      
3530      *                                                                                                   
3531      * This needs to be called from incoming places where resources might have been loaded               
3532      * while the activity is paused. That is because the Configuration (e.g., rotation)  might be        
3533      * wrong when we're not running, and if the activity comes back to what the configuration was        
3534      * when we were paused, activity is not restarted.                                                   
3535      *                                                                                                   
3536      * Implementation of the method from LauncherModel.Callbacks.                                        
3537      *                                                                                                   
3538      * @return true if we are currently paused.  The caller might be able to                             
3539     skip some work in that case since we will come back again.                                           
3540      */                                                                                                  
3541     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3542         if (mPaused) {                                                                                   
3543             if (LOGD) {                                                                                  
3544                 Log.d(TAG, "Deferring update until onResume");                                           
3545             }                                                                                            
3546             if (deletePreviousRunnables) {                                                               
3547                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3548                 }                                                                                        
3549             }                                                                                            
3550             mBindOnResumeCallbacks.add(run);                                                             
3551             return true;                                                                                 
3552         } else {                                                                                         
3553             return false;                                                                                
3554         }                                                                                                
3555     }                                                                                                    
3556                                                                                                          
3557     private boolean waitUntilResume(Runnable run) {                                                      
3558         return waitUntilResume(run, false);                                                              
3559     }                                                                                                    
3560                                                                                                          
3561     public void addOnResumeCallback(Runnable run) {                                                      
3562         mOnResumeCallbacks.add(run);                                                                     
3563     }                                                                                                    
3564                                                                                                          
3565     /**                                                                                                  
3566      * If the activity is currently paused, signal that we need to re-run the loader                     
3567      * in onResume.                                                                                      
3568      *                                                                                                   
3569      * This needs to be called from incoming places where resources might have been loaded               
3570      * while we are paused.  That is becaues the Configuration might be wrong                            
3571      * when we're not running, and if it comes back to what it was when we                               
3572      * were paused, we are not restarted.                                                                
3573      *                                                                                                   
3574      * Implementation of the method from LauncherModel.Callbacks.                                        
3575      *                                                                                                   
3576      * @return true if we are currently paused.  The caller might be able to                             
3577      * skip some work in that case since we will come back again.                                        
3578      */                                                                                                  
3579     public boolean setLoadOnResume() {                                                                   
3580         if (mPaused) {                                                                                   
3581             if (LOGD) {                                                                                  
3582                 Log.d(TAG, "setLoadOnResume");                                                           
3583             }                                                                                            
3584             mOnResumeNeedsLoad = true;                                                                   
3585             return true;                                                                                 
3586         } else {                                                                                         
3587             return false;                                                                                
3588         }                                                                                                
3589     }                                                                                                    
3590                                                                                                          
3591     /**                                                                                                  
3592      * Implementation of the method from LauncherModel.Callbacks.                                        
3593      */                                                                                                  
3594     public int getCurrentWorkspaceScreen() {                                                             
3595         if (mWorkspace != null) {                                                                        
3596             return mWorkspace.getCurrentPage();                                                          
3597         } else {                                                                                         
3598             return SCREEN_COUNT / 2;                                                                     
3599         }                                                                                                
3600     }                                                                                                    
3601                                                                                                          
3602     /**                                                                                                  
3603      * Refreshes the shortcuts shown on the workspace.                                                   
3604      *                                                                                                   
3605      * Implementation of the method from LauncherModel.Callbacks.                                        
3606      */                                                                                                  
3607     public void startBinding() {                                                                         
3608         setWorkspaceLoading(true);                                                                       
3609                                                                                                          
3610         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3611         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3612         // from scratch again                                                                            
3613         mBindOnResumeCallbacks.clear();                                                                  
3614                                                                                                          
3615         // Clear the workspace because it's going to be rebound                                          
3616         mWorkspace.clearDropTargets();                                                                   
3617         mWorkspace.removeAllWorkspaceScreens();                                                          
3618                                                                                                          
3619         mWidgetsToAdvance.clear();                                                                       
3620         if (mHotseat != null) {                                                                          
3621             mHotseat.resetLayout();                                                                      
3622         }                                                                                                
3623     }                                                                                                    
3624                                                                                                          
3625     @Override                                                                                            
3626     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3627         bindAddScreens(orderedScreenIds);                                                                
3628                                                                                                          
3629         // If there are no screens, we need to have an empty screen                                      
3630         if (orderedScreenIds.size() == 0) {                                                              
3631             mWorkspace.addExtraEmptyScreen();                                                            
3632         }                                                                                                
3633                                                                                                          
3634         // Create the custom content page (this call updates mDefaultScreen which calls                  
3635         // setCurrentPage() so ensure that all pages are added before calling this).                     
3636         if (hasCustomContentToLeft()) {                                                                  
3637             mWorkspace.createCustomContentContainer();                                                   
3638             populateCustomContentContainer();                                                            
3639         }                                                                                                
3640     }                                                                                                    
3641                                                                                                          
3642     @Override                                                                                            
3643     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3644         // Log to disk                                                                                   
3645         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3646         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3647                 TextUtils.join(", ", orderedScreenIds), true);                                           
3648         int count = orderedScreenIds.size();                                                             
3649         for (int i = 0; i < count; i++) {                                                                
3650             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3651         }                                                                                                
3652     }                                                                                                    
3653                                                                                                          
3654     private boolean shouldShowWeightWatcher() {                                                          
3655         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3656         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3657         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3658                                                                                                          
3659         return show;                                                                                     
3660     }                                                                                                    
3661                                                                                                          
3662     private void toggleShowWeightWatcher() {                                                             
3663         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3664         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3665         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3666                                                                                                          
3667         show = !show;                                                                                    
3668                                                                                                          
3669         SharedPreferences.Editor editor = sp.edit();                                                     
3670         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3671         editor.commit();                                                                                 
3672                                                                                                          
3673         if (mWeightWatcher != null) {                                                                    
3674             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3675         }                                                                                                
3676     }                                                                                                    
3677                                                                                                          
3678     public void bindAppsAdded(final ArrayList<Long> newScreens, final ArrayList<ItemInfo> addNotAnimated,🔵
3679         Runnable r = new Runnable() {                                                                    
3680             public void run() {                                                                          
3681                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3682             }                                                                                            
3683         };                                                                                               
3684         if (waitUntilResume(r)) {                                                                        
3685             return;                                                                                      
3686         }                                                                                                
3687         // Add the new screens                                                                           
3688         if (newScreens != null) {                                                                        
3689             bindAddScreens(newScreens);                                                                  
3690         }                                                                                                
3691         // We add the items without animation on non-visible pages, and with                             
3692         // animations on the new page (which we will try and snap to).                                   
3693         if ((addNotAnimated != null) && (!addNotAnimated.isEmpty())) {                                   
3694             bindItems(addNotAnimated, 0, addNotAnimated.size(), false);                                  
3695         }                                                                                                
3696         if ((addAnimated != null) && (!addAnimated.isEmpty())) {                                         
3697             bindItems(addAnimated, 0, addAnimated.size(), true);                                         
3698         }                                                                                                
3699         // Remove the extra empty screen                                                                 
3700         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3701         if ((addedApps != null) && (mAppsView != null)) {                                                
3702             mAppsView.addApps(addedApps);                                                                
3703         }                                                                                                
3704     }                                                                                                    
3705                                                                                                          
3706     /**                                                                                                  
3707      * Bind the items start-end from the list.                                                           
3708      *                                                                                                   
3709      * Implementation of the method from LauncherModel.Callbacks.                                        
3710      */                                                                                                  
3711     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3712                           final boolean forceAnimateIcons) {                                             
3713         Runnable r = new Runnable() {                                                                    
3714             public void run() {                                                                          
3715                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3716             }                                                                                            
3717         };                                                                                               
3718         if (waitUntilResume(r)) {                                                                        
3719             return;                                                                                      
3720         }                                                                                                
3721                                                                                                          
3722         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3723         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3724         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3725         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3726         Workspace workspace = mWorkspace;                                                                
3727         long newShortcutsScreenId = -1;                                                                  
3728         for (int i = start; i < end; i++) {                                                              
3729             final ItemInfo item = shortcuts.get(i);                                                      
3730                                                                                                          
3731             // Short circuit if we are loading dock items for a configuration which has no dock          
3732             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3733                     mHotseat == null) {                                                                  
3734                 continue;                                                                                
3735             }                                                                                            
3736                                                                                                          
3737             switch (item.itemType) {                                                                     
3738                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3739                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3740                     ShortcutInfo info = (ShortcutInfo) item;                                             
3741                     View shortcut = createShortcut(info);                                                
3742                                                                                                          
3743                     /*                                                                                   
3744                      * TODO: FIX collision case                                                          
3745                      */                                                                                  
3746                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3747                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3748                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3749                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3750                             Object tag = v.getTag();                                                     
3751                             String desc = "Collision while binding workspace item: " + item              
3752                                     + ". Collides with " + tag;                                          
3753                             if (LauncherAppState.isDogfoodBuild()) {                                     
3754                                 throw (new RuntimeException(desc));                                      
3755                             } else {                                                                     
3756                                 Log.d(TAG, desc);                                                        
3757                             }                                                                            
3758                         }                                                                                
3759                     }                                                                                    
3760                                                                                                          
3761                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3762                             item.cellY, 1, 1);                                                           
3763                     if (animateIcons) {                                                                  
3764                         // Animate all the applications up now                                           
3765                         shortcut.setAlpha(0f);                                                           
3766                         shortcut.setScaleX(0f);                                                          
3767                         shortcut.setScaleY(0f);                                                          
3768                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3769                         newShortcutsScreenId = item.screenId;                                            
3770                     }                                                                                    
3771                     break;                                                                               
3772                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3773                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3774                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3775                             (FolderInfo) item, mIconCache);                                              
3776                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3777                             item.cellY, 1, 1);                                                           
3778                     break;                                                                               
3779                 default:                                                                                 
3780                     throw new RuntimeException("Invalid Item Type");                                     
3781             }                                                                                            
3782         }                                                                                                
3783                                                                                                          
3784         if (animateIcons) {                                                                              
3785             // Animate to the correct page                                                               
3786             if (newShortcutsScreenId > -1) {                                                             
3787                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3788                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3789                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3790                     public void run() {                                                                  
3791                         anim.playTogether(bounceAnims);                                                  
3792                         anim.start();                                                                    
3793                     }                                                                                    
3794                 };                                                                                       
3795                 if (newShortcutsScreenId != currentScreenId) {                                           
3796                     // We post the animation slightly delayed to prevent slowdowns                       
3797                     // when we are loading right after we return to launcher.                            
3798                     mWorkspace.postDelayed(new Runnable() {                                              
3799                         public void run() {                                                              
3800                             if (mWorkspace != null) {                                                    
3801                                 mWorkspace.snapToPage(newScreenIndex);                                   
3802                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3803                                         NEW_APPS_ANIMATION_DELAY);                                       
3804                             }                                                                            
3805                         }                                                                                
3806                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3807                 } else {                                                                                 
3808                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3809                 }                                                                                        
3810             }                                                                                            
3811         }                                                                                                
3812         workspace.requestLayout();                                                                       
3813     }                                                                                                    
3814                                                                                                          
3815     /**                                                                                                  
3816      * Implementation of the method from LauncherModel.Callbacks.                                        
3817      */                                                                                                  
3818     public void bindFolders(final LongArrayMap<FolderInfo> folders) {                                    
3819         Runnable r = new Runnable() {                                                                    
3820             public void run() {                                                                          
3821                 bindFolders(folders);                                                                    
3822             }                                                                                            
3823         };                                                                                               
3824         if (waitUntilResume(r)) {                                                                        
3825             return;                                                                                      
3826         }                                                                                                
3827         sFolders = folders.clone();                                                                      
3828     }                                                                                                    
3829                                                                                                          
3830     /**                                                                                                  
3831      * Add the views for a widget to the workspace.                                                      
3832      *                                                                                                   
3833      * Implementation of the method from LauncherModel.Callbacks.                                        
3834      */                                                                                                  
3835     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3836         Runnable r = new Runnable() {                                                                    
3837             public void run() {                                                                          
3838                 bindAppWidget(item);                                                                     
3839             }                                                                                            
3840         };                                                                                               
3841         if (waitUntilResume(r)) {                                                                        
3842             return;                                                                                      
3843         }                                                                                                
3844         final long start = (DEBUG_WIDGETS) ? SystemClock.uptimeMillis() : 0;                             
3845         if (DEBUG_WIDGETS) {                                                                             
3846             Log.d(TAG, "bindAppWidget: " + item);                                                        
3847         }                                                                                                
3848         final Workspace workspace = mWorkspace;                                                          
3849         LauncherAppWidgetProviderInfo appWidgetInfo = LauncherModel.getProviderInfo(this, item.providerNa🔵
3850         if (((!mIsSafeModeEnabled) && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READ🔵
3851             if (appWidgetInfo == null) {                                                                 
3852                 if (DEBUG_WIDGETS) {                                                                     
3853                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
3854                 }                                                                                        
3855                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3856                 return;                                                                                  
3857             }                                                                                            
3858             // Note: This assumes that the id remap broadcast is received before this step.              
3859             // If that is not the case, the id remap will be ignored and user may see the                
3860             // click to setup view.                                                                      
3861             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);      
3862             pendingInfo.spanX = item.spanX;                                                              
3863             pendingInfo.spanY = item.spanY;                                                              
3864             pendingInfo.minSpanX = item.minSpanX;                                                        
3865             pendingInfo.minSpanY = item.minSpanY;                                                        
3866             Bundle options = null;                                                                       
3867             WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);                          
3868             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3869             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId, appWidgetInfo, opti🔵
3870             // TODO consider showing a permission dialog when the widget is clicked.                     
3871             if (!success) {                                                                              
3872                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3873                 if (DEBUG_WIDGETS) {                                                                     
3874                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
3875                 }                                                                                        
3876                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3877                 return;                                                                                  
3878             }                                                                                            
3879             item.appWidgetId = newWidgetId;                                                              
3880             // If the widget has a configure activity, it is still needs to set it up, otherwise         
3881             // the widget is ready to go.                                                                
3882             item.restoreStatus = (appWidgetInfo.configure == null) ? LauncherAppWidgetInfo.RESTORE_COMPLE🔵
3883             LauncherModel.updateItemInDatabase(this, item);                                              
3884         }                                                                                                
3885         if ((!mIsSafeModeEnabled) && (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED)) {  
3886             final int appWidgetId = item.appWidgetId;                                                    
3887             if (DEBUG_WIDGETS) {                                                                         
3888                 Log.d(TAG, (("bindAppWidget: id=" + item.appWidgetId) + " belongs to component ") + appWi🔵
3889             }                                                                                            
3890             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
3891         } else {                                                                                         
3892             appWidgetInfo = null;                                                                        
3893             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, mIsSafeModeEnabled);
3894             view.updateIcon(mIconCache);                                                                 
3895             item.hostView = view;                                                                        
3896             item.hostView.updateAppWidget(null);                                                         
3897             item.hostView.setOnClickListener(this);                                                      
3898         }                                                                                                
3899         item.hostView.setTag(item);                                                                      
3900         item.onBindAppWidget(this);                                                                      
3901         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX, item.cellY, item.🔵
3902         if (!item.isCustomWidget()) {                                                                    
3903             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
3904         }                                                                                                
3905         workspace.requestLayout();                                                                       
3906         if (DEBUG_WIDGETS) {                                                                             
3907             Log.d(TAG, ((("bound widget id=" + item.appWidgetId) + " in ") + (SystemClock.uptimeMillis() 🔵
3908         }                                                                                                
3909     }                                                                                                    
3910                                                                                                          
3911     /**                                                                                                  
3912      * Restores a pending widget.                                                                        
3913      *                                                                                                   
3914      * @param appWidgetId The app widget id                                                              
3915      * @param cellInfo The position on screen where to create the widget.                                
3916      */                                                                                                  
3917     private void completeRestoreAppWidget(final int appWidgetId) {                                       
3918         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
3919         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
3920             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
3921             return;                                                                                      
3922         }                                                                                                
3923                                                                                                          
3924         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
3925         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
3926                                                                                                          
3927         mWorkspace.reinflateWidgetsIfNecessary();                                                        
3928         LauncherModel.updateItemInDatabase(this, info);                                                  
3929     }                                                                                                    
3930                                                                                                          
3931     public void onPageBoundSynchronously(int page) {                                                     
3932         mSynchronouslyBoundPages.add(page);                                                              
3933     }                                                                                                    
3934                                                                                                          
3935     /**                                                                                                  
3936      * Callback saying that there aren't any more items to bind.                                         
3937      *                                                                                                   
3938      * Implementation of the method from LauncherModel.Callbacks.                                        
3939      */                                                                                                  
3940     public void finishBindingItems() {                                                                   
3941         Runnable r = new Runnable() {                                                                    
3942             public void run() {                                                                          
3943                 finishBindingItems();                                                                    
3944             }                                                                                            
3945         };                                                                                               
3946         if (waitUntilResume(r)) {                                                                        
3947             return;                                                                                      
3948         }                                                                                                
3949         if (mSavedState != null) {                                                                       
3950             if (!mWorkspace.hasFocus()) {                                                                
3951                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
3952             }                                                                                            
3953             mSavedState = null;                                                                          
3954         }                                                                                                
3955         mWorkspace.restoreInstanceStateForRemainingPages();                                              
3956         setWorkspaceLoading(false);                                                                      
3957         sendLoadingCompleteBroadcastIfNecessary();                                                       
3958         // If we received the result of any pending adds while the loader was running (e.g. the          
3959         // widget configuration forced an orientation change), process them now.                         
3960         if (sPendingAddItem != null) {                                                                   
3961             final long screenId = completeAdd(sPendingAddItem);                                          
3962             // TODO: this moves the user to the page where the pending item was added. Ideally,          
3963             // the screen would be guaranteed to exist after bind, and the page would be set through     
3964             // the workspace restore process.                                                            
3965             mWorkspace.post(new Runnable() {                                                             
3966                 @Override                                                                                
3967                 public void run() {                                                                      
3968                     mWorkspace.snapToScreenId(screenId);                                                 
3969                 }                                                                                        
3970             });                                                                                          
3971             sPendingAddItem = null;                                                                      
3972         }                                                                                                
3973         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
3974         if (mLauncherCallbacks != null) {                                                                
3975             mLauncherCallbacks.finishBindingItems(false);                                                
3976         }                                                                                                
3977     }                                                                                                    
3978                                                                                                          
3979     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
3980         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
3981             String permission =                                                                          
3982                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
3983             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
3984             sendBroadcast(intent, permission);                                                           
3985             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
3986             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
3987             editor.apply();                                                                              
3988         }                                                                                                
3989     }                                                                                                    
3990                                                                                                          
3991     public boolean isAllAppsButtonRank(int rank) {                                                       
3992         if (mHotseat != null) {                                                                          
3993             return mHotseat.isAllAppsButtonRank(rank);                                                   
3994         }                                                                                                
3995         return false;                                                                                    
3996     }                                                                                                    
3997                                                                                                          
3998     private boolean canRunNewAppsAnimation() {                                                           
3999         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4000         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4001     }                                                                                                    
4002                                                                                                          
4003     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4004         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4005                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4006                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4007                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4008         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4009         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4010         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4011         return bounceAnim;                                                                               
4012     }                                                                                                    
4013                                                                                                          
4014     public boolean useVerticalBarLayout() {                                                              
4015         return mDeviceProfile.isVerticalBarLayout();                                                     
4016     }                                                                                                    
4017                                                                                                          
4018     protected Rect getSearchBarBounds() {                                                                
4019         return mDeviceProfile.getSearchBarBounds(Utilities.isRtl(getResources()));                       
4020     }                                                                                                    
4021                                                                                                          
4022     public void bindSearchablesChanged() {                                                               
4023         if (mSearchDropTargetBar == null) {                                                              
4024             return;                                                                                      
4025         }                                                                                                
4026         if (mQsb != null) {                                                                              
4027             mSearchDropTargetBar.removeView(mQsb);                                                       
4028             mQsb = null;                                                                                 
4029         }                                                                                                
4030         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4031     }                                                                                                    
4032                                                                                                          
4033     /**                                                                                                  
4034      * A runnable that we can dequeue and re-enqueue when all applications are bound (to prevent         
4035      * multiple calls to bind the same list.)                                                            
4036      */                                                                                                  
4037     @Thunk ArrayList<AppInfo> mTmpAppsList;                                                              
4038                                                                                                          
4039     private Runnable mBindAllApplicationsRunnable = new Runnable() {                                     
4040         public void run() {                                                                              
4041             bindAllApplications(mTmpAppsList);                                                           
4042             mTmpAppsList = null;                                                                         
4043         }                                                                                                
4044     };                                                                                                   
4045                                                                                                          
4046     /**                                                                                                  
4047      * Add the icons for all apps.                                                                       
4048      *                                                                                                   
4049      * Implementation of the method from LauncherModel.Callbacks.                                        
4050      */                                                                                                  
4051     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4052         if (waitUntilResume(mBindAllApplicationsRunnable, true)) {                                       
4053             mTmpAppsList = apps;                                                                         
4054             return;                                                                                      
4055         }                                                                                                
4056         if (mAppsView != null) {                                                                         
4057             mAppsView.setApps(apps);                                                                     
4058         }                                                                                                
4059         if (mLauncherCallbacks != null) {                                                                
4060             mLauncherCallbacks.bindAllApplications(apps);                                                
4061         }                                                                                                
4062     }                                                                                                    
4063                                                                                                          
4064     /**                                                                                                  
4065      * A package was updated.                                                                            
4066      *                                                                                                   
4067      * Implementation of the method from LauncherModel.Callbacks.                                        
4068      */                                                                                                  
4069     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4070         Runnable r = new Runnable() {                                                                    
4071             public void run() {                                                                          
4072                 bindAppsUpdated(apps);                                                                   
4073             }                                                                                            
4074         };                                                                                               
4075         if (waitUntilResume(r)) {                                                                        
4076             return;                                                                                      
4077         }                                                                                                
4078         if (mAppsView != null) {                                                                         
4079             mAppsView.updateApps(apps);                                                                  
4080         }                                                                                                
4081     }                                                                                                    
4082                                                                                                          
4083     @Override                                                                                            
4084     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4085         Runnable r = new Runnable() {                                                                    
4086             public void run() {                                                                          
4087                 bindWidgetsRestored(widgets);                                                            
4088             }                                                                                            
4089         };                                                                                               
4090         if (waitUntilResume(r)) {                                                                        
4091             return;                                                                                      
4092         }                                                                                                
4093         mWorkspace.widgetsRestored(widgets);                                                             
4094     }                                                                                                    
4095                                                                                                          
4096     /**                                                                                                  
4097      * Some shortcuts were updated in the background.                                                    
4098      *                                                                                                   
4099      * Implementation of the method from LauncherModel.Callbacks.                                        
4100      */                                                                                                  
4101     @Override                                                                                            
4102     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4103             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4104         Runnable r = new Runnable() {                                                                    
4105             public void run() {                                                                          
4106                 bindShortcutsChanged(updated, removed, user);                                            
4107             }                                                                                            
4108         };                                                                                               
4109         if (waitUntilResume(r)) {                                                                        
4110             return;                                                                                      
4111         }                                                                                                
4112                                                                                                          
4113         if (!updated.isEmpty()) {                                                                        
4114             mWorkspace.updateShortcuts(updated);                                                         
4115         }                                                                                                
4116                                                                                                          
4117         if (!removed.isEmpty()) {                                                                        
4118             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4119             for (ShortcutInfo si : removed) {                                                            
4120                 removedComponents.add(si.getTargetComponent());                                          
4121             }                                                                                            
4122             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4123             // Notify the drag controller                                                                
4124             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4125         }                                                                                                
4126     }                                                                                                    
4127                                                                                                          
4128     /**                                                                                                  
4129      * Update the state of a package, typically related to install state.                                
4130      *                                                                                                   
4131      * Implementation of the method from LauncherModel.Callbacks.                                        
4132      */                                                                                                  
4133     @Override                                                                                            
4134     public void bindRestoreItemsChange(final HashSet<ItemInfo> updates) {                                
4135         Runnable r = new Runnable() {                                                                    
4136             public void run() {                                                                          
4137                 bindRestoreItemsChange(updates);                                                         
4138             }                                                                                            
4139         };                                                                                               
4140         if (waitUntilResume(r)) {                                                                        
4141             return;                                                                                      
4142         }                                                                                                
4143         mWorkspace.updateRestoreItems(updates);                                                          
4144     }                                                                                                    
4145                                                                                                          
4146     /**                                                                                                  
4147      * A package was uninstalled.  We take both the super set of packageNames                            
4148      * in addition to specific applications to remove, the reason being that                             
4149      * this can be called when a package is updated as well.  In that scenario,                          
4150      * we only remove specific components from the workspace, where as                                   
4151      * package-removal should clear all items by package name.                                           
4152      *                                                                                                   
4153      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4154      * Implementation of the method from LauncherModel.Callbacks.                                        
4155      */                                                                                                  
4156     @Override                                                                                            
4157     public void bindComponentsRemoved(final ArrayList<String> packageNames, final ArrayList<AppInfo> appI🔵
4158         Runnable r = new Runnable() {                                                                    
4159             public void run() {                                                                          
4160                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4161             }                                                                                            
4162         };                                                                                               
4163         if (waitUntilResume(r)) {                                                                        
4164             return;                                                                                      
4165         }                                                                                                
4166         if (reason == 0) {                                                                               
4167             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4168             for (AppInfo info : appInfos) {                                                              
4169                 removedComponents.add(info.componentName);                                               
4170             }                                                                                            
4171             if (!packageNames.isEmpty()) {                                                               
4172                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4173             }                                                                                            
4174             if (!removedComponents.isEmpty()) {                                                          
4175                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4176             }                                                                                            
4177             // Notify the drag controller                                                                
4178             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4179         } else {                                                                                         
4180             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4181         }                                                                                                
4182         // Update AllApps                                                                                
4183         if (mAppsView != null) {                                                                         
4184             mAppsView.removeApps(appInfos);                                                              
4185         }                                                                                                
4186     }                                                                                                    
4187                                                                                                          
4188     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4189             public void run() {                                                                          
4190                 bindAllPackages(mWidgetsModel);                                                          
4191             }                                                                                            
4192         };                                                                                               
4193                                                                                                          
4194     @Override                                                                                            
4195     public void bindAllPackages(final WidgetsModel model) {                                              
4196         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4197             mWidgetsModel = model;                                                                       
4198             return;                                                                                      
4199         }                                                                                                
4200         if ((mWidgetsView != null) && (model != null)) {                                                 
4201             mWidgetsView.addWidgets(model);                                                              
4202             mWidgetsModel = null;                                                                        
4203         }                                                                                                
4204     }                                                                                                    
4205                                                                                                          
4206     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4207         final Display d = getWindowManager().getDefaultDisplay();                                        
4208         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4209         switch (d.getRotation()) {                                                                       
4210         case Surface.ROTATION_0:                                                                         
4211         case Surface.ROTATION_180:                                                                       
4212             // We are currently in the same basic orientation as the natural orientation                 
4213             naturalOri = configOri;                                                                      
4214             break;                                                                                       
4215         case Surface.ROTATION_90:                                                                        
4216         case Surface.ROTATION_270:                                                                       
4217             // We are currently in the other basic orientation to the natural orientation                
4218             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4219                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4220             break;                                                                                       
4221         }                                                                                                
4222                                                                                                          
4223         int[] oriMap = {                                                                                 
4224                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4225                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4226                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4227                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4228         };                                                                                               
4229         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4230         // is landscape.                                                                                 
4231         int indexOffset = 0;                                                                             
4232         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4233             indexOffset = 1;                                                                             
4234         }                                                                                                
4235         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4236     }                                                                                                    
4237                                                                                                          
4238     public void lockScreenOrientation() {                                                                
4239         if (Utilities.isRotationEnabled(this)) {                                                         
4240             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4241                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4242                         .getConfiguration().orientation));                                               
4243             } else {                                                                                     
4244                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4245             }                                                                                            
4246         }                                                                                                
4247     }                                                                                                    
4248                                                                                                          
4249     public void unlockScreenOrientation(boolean immediate) {                                             
4250         if (Utilities.isRotationEnabled(this)) {                                                         
4251             if (immediate) {                                                                             
4252                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4253             } else {                                                                                     
4254                 mHandler.postDelayed(new Runnable() {                                                    
4255                     public void run() {                                                                  
4256                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4257                     }                                                                                    
4258                 }, mRestoreScreenOrientationDelay);                                                      
4259             }                                                                                            
4260         }                                                                                                
4261     }                                                                                                    
4262                                                                                                          
4263     protected boolean isLauncherPreinstalled() {                                                         
4264         if (mLauncherCallbacks != null) {                                                                
4265             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4266         }                                                                                                
4267         PackageManager pm = getPackageManager();                                                         
4268         try {                                                                                            
4269             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4270             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4271                 return true;                                                                             
4272             } else {                                                                                     
4273                 return false;                                                                            
4274             }                                                                                            
4275         } catch (NameNotFoundException e) {                                                              
4276             e.printStackTrace();                                                                         
4277             return false;                                                                                
4278         }                                                                                                
4279     }                                                                                                    
4280                                                                                                          
4281     /**                                                                                                  
4282      * This method indicates whether or not we should suggest default wallpaper dimensions               
4283      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4284      */                                                                                                  
4285     protected boolean overrideWallpaperDimensions() {                                                    
4286         if (mLauncherCallbacks != null) {                                                                
4287             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4288         }                                                                                                
4289         return true;                                                                                     
4290     }                                                                                                    
4291                                                                                                          
4292     /**                                                                                                  
4293      * To be overridden by subclasses to indicate that there is an activity to launch                    
4294      * before showing the standard launcher experience.                                                  
4295      */                                                                                                  
4296     protected boolean hasFirstRunActivity() {                                                            
4297         if (mLauncherCallbacks != null) {                                                                
4298             return mLauncherCallbacks.hasFirstRunActivity();                                             
4299         }                                                                                                
4300         return false;                                                                                    
4301     }                                                                                                    
4302                                                                                                          
4303     /**                                                                                                  
4304      * To be overridden by subclasses to launch any first run activity                                   
4305      */                                                                                                  
4306     protected Intent getFirstRunActivity() {                                                             
4307         if (mLauncherCallbacks != null) {                                                                
4308             return mLauncherCallbacks.getFirstRunActivity();                                             
4309         }                                                                                                
4310         return null;                                                                                     
4311     }                                                                                                    
4312                                                                                                          
4313     /**                                                                                                  
4314      * Returns whether the launcher callbacks overrides search in all apps.                              
4315      */                                                                                                  
4316     @Thunk                                                                                               
4317     boolean isAllAppsSearchOverridden() {                                                                
4318         if (DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                       
4319             return false;                                                                                
4320         }                                                                                                
4321         if (mLauncherCallbacks != null) {                                                                
4322             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4323         }                                                                                                
4324         return false;                                                                                    
4325     }                                                                                                    
4326                                                                                                          
4327     private boolean shouldRunFirstRunActivity() {                                                        
4328         return !ActivityManager.isRunningInTestHarness() &&                                              
4329                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4330     }                                                                                                    
4331                                                                                                          
4332     protected boolean hasRunFirstRunActivity() {                                                         
4333         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4334     }                                                                                                    
4335                                                                                                          
4336     public boolean showFirstRunActivity() {                                                              
4337         if (shouldRunFirstRunActivity() &&                                                               
4338                 hasFirstRunActivity()) {                                                                 
4339             Intent firstRunIntent = getFirstRunActivity();                                               
4340             if (firstRunIntent != null) {                                                                
4341                 startActivity(firstRunIntent);                                                           
4342                 markFirstRunActivityShown();                                                             
4343                 return true;                                                                             
4344             }                                                                                            
4345         }                                                                                                
4346         return false;                                                                                    
4347     }                                                                                                    
4348                                                                                                          
4349     private void markFirstRunActivityShown() {                                                           
4350         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4351         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4352         editor.apply();                                                                                  
4353     }                                                                                                    
4354                                                                                                          
4355     /**                                                                                                  
4356      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4357      * screen that must be displayed and dismissed.                                                      
4358      */                                                                                                  
4359     protected boolean hasDismissableIntroScreen() {                                                      
4360         if (mLauncherCallbacks != null) {                                                                
4361             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4362         }                                                                                                
4363         return false;                                                                                    
4364     }                                                                                                    
4365                                                                                                          
4366     /**                                                                                                  
4367      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4368      */                                                                                                  
4369     protected View getIntroScreen() {                                                                    
4370         if (mLauncherCallbacks != null) {                                                                
4371             return mLauncherCallbacks.getIntroScreen();                                                  
4372         }                                                                                                
4373         return null;                                                                                     
4374     }                                                                                                    
4375                                                                                                          
4376     /**                                                                                                  
4377      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4378      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4379      */                                                                                                  
4380     private boolean shouldShowIntroScreen() {                                                            
4381         return hasDismissableIntroScreen() &&                                                            
4382                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4383     }                                                                                                    
4384                                                                                                          
4385     protected void showIntroScreen() {                                                                   
4386         View introScreen = getIntroScreen();                                                             
4387         changeWallpaperVisiblity(false);                                                                 
4388         if (introScreen != null) {                                                                       
4389             mDragLayer.showOverlayView(introScreen);                                                     
4390         }                                                                                                
4391         if (mLauncherOverlayContainer != null) {                                                         
4392             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4393         }                                                                                                
4394     }                                                                                                    
4395                                                                                                          
4396     public void dismissIntroScreen() {                                                                   
4397         markIntroScreenDismissed();                                                                      
4398         if (showFirstRunActivity()) {                                                                    
4399             // We delay hiding the intro view until the first run activity is showing. This              
4400             // avoids a blip.                                                                            
4401             mWorkspace.postDelayed(new Runnable() {                                                      
4402                 @Override                                                                                
4403                 public void run() {                                                                      
4404                     mDragLayer.dismissOverlayView();                                                     
4405                     if (mLauncherOverlayContainer != null) {                                             
4406                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4407                     }                                                                                    
4408                     showFirstRunClings();                                                                
4409                 }                                                                                        
4410             }, ACTIVITY_START_DELAY);                                                                    
4411         } else {                                                                                         
4412             mDragLayer.dismissOverlayView();                                                             
4413             if (mLauncherOverlayContainer != null) {                                                     
4414                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4415             }                                                                                            
4416             showFirstRunClings();                                                                        
4417         }                                                                                                
4418         changeWallpaperVisiblity(true);                                                                  
4419     }                                                                                                    
4420                                                                                                          
4421     private void markIntroScreenDismissed() {                                                            
4422         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4423         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4424         editor.apply();                                                                                  
4425     }                                                                                                    
4426                                                                                                          
4427     @Thunk                                                                                               
4428     void showFirstRunClings() {                                                                          
4429         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4430         // on the device, then we always show the first run cling experience (or if there is no          
4431         // launcher2). Otherwise, we prompt the user upon started for migration                          
4432         LauncherClings launcherClings = new LauncherClings(this);                                        
4433         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4434             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4435                 launcherClings.showMigrationCling();                                                     
4436             } else {                                                                                     
4437                 launcherClings.showLongPressCling(true);                                                 
4438             }                                                                                            
4439         }                                                                                                
4440     }                                                                                                    
4441                                                                                                          
4442     void showWorkspaceSearchAndHotseat() {                                                               
4443         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4444         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4445         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4446         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4447     }                                                                                                    
4448                                                                                                          
4449     void hideWorkspaceSearchAndHotseat() {                                                               
4450         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4451         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4452         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4453         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4454     }                                                                                                    
4455                                                                                                          
4456     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4457         // Called from search suggestion, not supported in other profiles.                               
4458         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4459         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4460         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent, myUser); 
4461         if (activityInfo == null) {                                                                      
4462             return null;                                                                                 
4463         }                                                                                                
4464         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4465     }                                                                                                    
4466                                                                                                          
4467     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4468             Bitmap icon) {                                                                               
4469         // Called from search suggestion, not supported in other profiles.                               
4470         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4471                 UserHandleCompat.myUserHandle());                                                        
4472     }                                                                                                    
4473                                                                                                          
4474     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4475             Bitmap icon, UserHandleCompat user) {                                                        
4476         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4477         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4478         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4479     }                                                                                                    
4480                                                                                                          
4481     protected void moveWorkspaceToDefaultScreen() {                                                      
4482         mWorkspace.moveToDefaultScreen(false);                                                           
4483     }                                                                                                    
4484                                                                                                          
4485     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4486         dragView.setTag(dragInfo);                                                                       
4487         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4488         mWorkspace.beginExternalDragShared(dragView, source);                                            
4489     }                                                                                                    
4490                                                                                                          
4491     @Override                                                                                            
4492     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4493         if (mLauncherCallbacks != null) {                                                                
4494             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4495         }                                                                                                
4496     }                                                                                                    
4497                                                                                                          
4498     /**                                                                                                  
4499      * Prints out out state for debugging.                                                               
4500      */                                                                                                  
4501     public void dumpState() {                                                                            
4502         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4503         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4504         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4505         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4506         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4507         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4508         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4509         mModel.dumpState();                                                                              
4510         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4511         Log.d(TAG, "END launcher3 dump state");                                                          
4512     }                                                                                                    
4513                                                                                                          
4514     @Override                                                                                            
4515     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4516         super.dump(prefix, fd, writer, args);                                                            
4517         synchronized (sDumpLogs) {                                                                       
4518             writer.println(" ");                                                                         
4519             writer.println("Debug logs: ");                                                              
4520             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4521                 writer.println("  " + sDumpLogs.get(i));                                                 
4522             }                                                                                            
4523         }                                                                                                
4524         if (mLauncherCallbacks != null) {                                                                
4525             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4526         }                                                                                                
4527     }                                                                                                    
4528                                                                                                          
4529     public static void dumpDebugLogsToConsole() {                                                        
4530         if (DEBUG_DUMP_LOG) {                                                                            
4531             synchronized (sDumpLogs) {                                                                   
4532                 Log.d(TAG, "");                                                                          
4533                 Log.d(TAG, "*********************");                                                     
4534                 Log.d(TAG, "Launcher debug logs: ");                                                     
4535                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4536                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4537                 }                                                                                        
4538                 Log.d(TAG, "*********************");                                                     
4539                 Log.d(TAG, "");                                                                          
4540             }                                                                                            
4541         }                                                                                                
4542     }                                                                                                    
4543                                                                                                          
4544     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4545         addDumpLog(tag, log, null, debugLog);                                                            
4546     }                                                                                                    
4547                                                                                                          
4548     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4549         if (debugLog) {                                                                                  
4550             if (e != null) {                                                                             
4551                 Log.d(tag, log, e);                                                                      
4552             } else {                                                                                     
4553                 Log.d(tag, log);                                                                         
4554             }                                                                                            
4555         }                                                                                                
4556         if (DEBUG_DUMP_LOG) {                                                                            
4557             sDateStamp.setTime(System.currentTimeMillis());                                              
4558             synchronized (sDumpLogs) {                                                                   
4559                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4560                     + (e == null ? "" : (", Exception: " + e)));                                         
4561             }                                                                                            
4562         }                                                                                                
4563     }                                                                                                    
4564                                                                                                          
4565     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4566         return sCustomAppWidgets.get(name);                                                              
4567     }                                                                                                    
4568                                                                                                          
4569     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4570         return sCustomAppWidgets;                                                                        
4571     }                                                                                                    
4572                                                                                                          
4573     public void dumpLogsToLocalData() {                                                                  
4574         if (DEBUG_DUMP_LOG) {                                                                            
4575             new AsyncTask<Void, Void, Void>() {                                                          
4576                 public Void doInBackground(Void ... args) {                                              
4577                     boolean success = false;                                                             
4578                     sDateStamp.setTime(sRunStart);                                                       
4579                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4580                             + sDateStamp.getDay() + "_"                                                  
4581                             + sDateStamp.getHours() + "-"                                                
4582                             + sDateStamp.getMinutes() + "_"                                              
4583                             + sDateStamp.getSeconds() + ".txt";                                          
4584                                                                                                          
4585                     FileOutputStream fos = null;                                                         
4586                     File outFile = null;                                                                 
4587                     try {                                                                                
4588                         outFile = new File(getFilesDir(), FILENAME);                                     
4589                         outFile.createNewFile();                                                         
4590                         fos = new FileOutputStream(outFile);                                             
4591                     } catch (Exception e) {                                                              
4592                         e.printStackTrace();                                                             
4593                     }                                                                                    
4594                     if (fos != null) {                                                                   
4595                         PrintWriter writer = new PrintWriter(fos);                                       
4596                                                                                                          
4597                         writer.println(" ");                                                             
4598                         writer.println("Debug logs: ");                                                  
4599                         synchronized (sDumpLogs) {                                                       
4600                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4601                                 writer.println("  " + sDumpLogs.get(i));                                 
4602                             }                                                                            
4603                         }                                                                                
4604                         writer.close();                                                                  
4605                     }                                                                                    
4606                     try {                                                                                
4607                         if (fos != null) {                                                               
4608                             fos.close();                                                                 
4609                             success = true;                                                              
4610                         }                                                                                
4611                     } catch (IOException e) {                                                            
4612                         e.printStackTrace();                                                             
4613                     }                                                                                    
4614                     return null;                                                                         
4615                 }                                                                                        
4616             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4617         }                                                                                                
4618     }                                                                                                    
4619 }                                                                                                        













































































































































































































































































ours vs. base theirs vs. base
   1 -                                                                                                                  
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25 -import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27 +import android.annotation.SuppressLint;                                                                           
  28  import android.annotation.TargetApi;                                                                              
  29  import android.app.Activity;                                                                                      
  30  import android.app.ActivityManager;                                                                               
  31  import android.app.ActivityOptions;                                                                               
  32  import android.app.AlertDialog;                                                                                   
  33  import android.app.SearchManager;                                                                                 
  34  import android.appwidget.AppWidgetHostView;                                                                       
  35  import android.appwidget.AppWidgetManager;                                                                        
  36  import android.appwidget.AppWidgetProviderInfo;                                                                   
  37  import android.content.ActivityNotFoundException;                                                                 
  38  import android.content.BroadcastReceiver;                                                                         
  39  import android.content.ComponentCallbacks2;                                                                       
  40  import android.content.ComponentName;                                                                             
  41  import android.content.ContentResolver;                                                                           
  42  import android.content.Context;                                                                                   
  43  import android.content.DialogInterface;                                                                           
  44  import android.content.Intent;                                                                                    
  45  import android.content.IntentFilter;                                                                              
  46  import android.content.IntentSender;                                                                              
  47  import android.content.SharedPreferences;                                                                         
  48  import android.content.pm.ActivityInfo;                                                                           
  49  import android.content.pm.ApplicationInfo;                                                                        
  50  import android.content.pm.PackageManager;                                                                         
  51  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  52  import android.content.res.Configuration;                                                                         
  53 -import android.content.res.Resources;                                                                             
  54  import android.database.ContentObserver;                                                                          
  55  import android.database.sqlite.SQLiteDatabase;                                                                    
  56  import android.graphics.Bitmap;                                                                                   
  57  import android.graphics.Canvas;                                                                                   
  58  import android.graphics.Color;                                                                                    
  59  import android.graphics.PorterDuff;                                                                               
  60  import android.graphics.Rect;                                                                                     
  61 +import android.graphics.drawable.ColorDrawable;                                                                   
  62  import android.graphics.drawable.Drawable;                                                                        
  63  import android.net.Uri;                                                                                           
  64  import android.os.AsyncTask;                                                                                      
  65  import android.os.Build;                                                                                          
  66  import android.os.Bundle;                                                                                         
  67  import android.os.Environment;                                                                                    
  68  import android.os.Handler;                                                                                        
  69  import android.os.Message;                                                                                        
  70  import android.os.StrictMode;                                                                                     
  71  import android.os.SystemClock;                                                                                    
  72  import android.text.Selection;                                                                                    
  73  import android.text.SpannableStringBuilder;                                                                       
  74  import android.text.TextUtils;                                                                                    
  75  import android.text.method.TextKeyListener;                                                                       
  76  import android.util.Log;                                                                                          
  77  import android.view.Display;                                                                                      
  78  import android.view.Gravity;                                                                                      
  79  import android.view.HapticFeedbackConstants;                                                                      
  80  import android.view.KeyEvent;                                                                                     
  81  import android.view.LayoutInflater;                                                                               
  82  import android.view.Menu;                                                                                         
  83  import android.view.MotionEvent;                                                                                  
  84  import android.view.Surface;                                                                                      
  85  import android.view.View;                                                                                         
  86  import android.view.View.OnClickListener;                                                                         
  87  import android.view.View.OnLongClickListener;                                                                     
  88 -import android.view.ViewAnimationUtils;                                                                           
  89  import android.view.ViewGroup;                                                                                    
  90  import android.view.ViewStub;                                                                                     
  91  import android.view.ViewTreeObserver;                                                                             
  92  import android.view.Window;                                                                                       
  93  import android.view.WindowManager;                                                                                
  94  import android.view.accessibility.AccessibilityEvent;                                                             
  95 -import android.view.animation.AccelerateInterpolator;                                                             
  96 -import android.view.animation.DecelerateInterpolator;                                                             
  97  import android.view.inputmethod.InputMethodManager;                                                               
  98  import android.widget.Advanceable;                                                                                
  99  import android.widget.FrameLayout;                                                                                
 100  import android.widget.ImageView;                                                                                  
 101 +import android.widget.TextView;                                                                                   
 102  import android.widget.Toast;                                                                                      
 103                                                                                                                    
 104  import com.android.launcher3.DropTarget.DragObject;                                                               
 105  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 106 +import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;                                         
 107 +import com.android.launcher3.allapps.AllAppsContainerView;                                                        
 108  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 109  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 110  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 111 -import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 112 -import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 113  import com.android.launcher3.compat.UserHandleCompat;                                                             
 114  import com.android.launcher3.compat.UserManagerCompat;                                                            
 115 +import com.android.launcher3.model.WidgetsModel;                                                                  
 116 +import com.android.launcher3.util.LongArrayMap;                                                                   
 117 +import com.android.launcher3.util.Thunk;                                                                          
 118 +import com.android.launcher3.widget.PendingAddWidgetInfo;                                                         
 119 +import com.android.launcher3.widget.WidgetHostViewLoader;                                                         
 120 +import com.android.launcher3.widget.WidgetsContainerView;                                                         
 121                                                                                                                    
 122  import java.io.DataInputStream;                                                                                   
 123  import java.io.DataOutputStream;                                                                                  
 124  import java.io.File;                                                                                              
 125  import java.io.FileDescriptor;                                                                                    
 126  import java.io.FileNotFoundException;                                                                             
 127  import java.io.FileOutputStream;                                                                                  
 128  import java.io.IOException;                                                                                       
 129  import java.io.PrintWriter;                                                                                       
 130 -import java.lang.reflect.Field;                                                                                   
 131  import java.lang.reflect.InvocationTargetException;                                                               
 132  import java.lang.reflect.Method;                                                                                  
 133  import java.text.DateFormat;                                                                                      
 134  import java.util.ArrayList;                                                                                       
 135  import java.util.Collection;                                                                                      
 136  import java.util.Date;                                                                                            
 137  import java.util.HashMap;                                                                                         
 138  import java.util.HashSet;                                                                                         
 139  import java.util.List;                                                                                            
 140  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 141                                                                                                                    
 142  /**                                                                                                               
 143   * Default launcher application.                                                                                  
 144   */                                                                                                               
 145  public class Launcher extends Activity                                                                            
 146          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 147 -                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 148 +                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,                      
 149 +                   LauncherStateTransitionAnimation.Callbacks {                                                   
 150      static final String TAG = "Launcher";                                                                         
 151      static final boolean LOGD = false;                                                                            
 152                                                                                                                    
 153 +    // Temporary flag                                                                                             
 154 +    static final boolean DISABLE_ALL_APPS_SEARCH_INTEGRATION = true;                                              
 155 +                                                                                                                  
 156      static final boolean PROFILE_STARTUP = false;                                                                 
 157 -    static final boolean DEBUG_WIDGETS = false;                                                                   
 158 +    static final boolean DEBUG_WIDGETS = true;                                                                    
 159      static final boolean DEBUG_STRICT_MODE = false;                                                               
 160      static final boolean DEBUG_RESUME_TIME = false;                                                               
 161      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 162                                                                                                                    
 163      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 164                                                                                                                    
 165      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 166      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 167 -    private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 168      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 169      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 170                                                                                                                    
 171      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 172      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 173 +                                                                                                                  
 174 +    private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;                                                   
 175 +    private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;                                                
 176 +    private static final int WORKSPACE_BACKGROUND_BLACK = 2;                                                      
 177                                                                                                                    
 178      /**                                                                                                           
 179       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 180       * request codes used internally.                                                                             
 181       */                                                                                                           
 182      protected static final int REQUEST_LAST = 100;                                                                
 183                                                                                                                    
 184      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 185                                                                                                                    
 186      static final int SCREEN_COUNT = 5;                                                                            
 187                                                                                                                    
 188      // To turn on these properties, type                                                                          
 189      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 190      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 191 -    static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 192                                                                                                                    
 193      // The Intent extra that defines whether to ignore the launch animation                                       
 194      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 195              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 196                                                                                                                    
 197      // Type: int                                                                                                  
 198      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 199      // Type: int                                                                                                  
 200      private static final String RUNTIME_STATE = "launcher.state";                                                 
 201      // Type: int                                                                                                  
 202      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 203      // Type: int                                                                                                  
 204      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 205      // Type: int                                                                                                  
 206      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 207      // Type: int                                                                                                  
 208      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 209 -    // Type: boolean                                                                                              
 210 -    private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 211 -    // Type: long                                                                                                 
 212 -    private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 213      // Type: int                                                                                                  
 214      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 215      // Type: int                                                                                                  
 216      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 217      // Type: parcelable                                                                                           
 218      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 219      // Type: parcelable                                                                                           
 220      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 221      // Type: int[]                                                                                                
 222      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 223                                                                                                                    
 224      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 225      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 226                                                                                                                    
 227      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 228      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 229              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 230                                                                                                                    
 231      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 232      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 233                                                                                                                    
 234      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 235      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 236                                                                                                                    
 237      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 238                                                                                                                    
 239      /** The different states that Launcher can be in. */                                                          
 240 -    private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 241 -    private State mState = State.WORKSPACE;                                                                       
 242 -    private AnimatorSet mStateAnimation;                                                                          
 243 +    enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };                     
 244 +    @Thunk State mState = State.WORKSPACE;                                                                        
 245 +    @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                            
 246                                                                                                                    
 247      private boolean mIsSafeModeEnabled;                                                                           
 248                                                                                                                    
 249      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 250      LauncherOverlay mLauncherOverlay;                                                                             
 251      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 252                                                                                                                    
 253      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 254      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 255      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 256      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 257                                                                                                                    
 258 -    private static final Object sLock = new Object();                                                             
 259 -                                                                                                                  
 260      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 261      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 262                                                                                                                    
 263      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 264      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 265      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 266 -    private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 267 -    private static final int SINGLE_FRAME_DELAY = 16;                                                             
 268 +    @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                             
 269                                                                                                                    
 270      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 271              = new CloseSystemDialogsIntentReceiver();                                                             
 272      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 273                                                                                                                    
 274      private LayoutInflater mInflater;                                                                             
 275                                                                                                                    
 276 -    private Workspace mWorkspace;                                                                                 
 277 +    @Thunk Workspace mWorkspace;                                                                                  
 278      private View mLauncherView;                                                                                   
 279      private View mPageIndicators;                                                                                 
 280 -    private DragLayer mDragLayer;                                                                                 
 281 +    @Thunk DragLayer mDragLayer;                                                                                  
 282      private DragController mDragController;                                                                       
 283      private View mWeightWatcher;                                                                                  
 284                                                                                                                    
 285      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 286      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 287                                                                                                                    
 288 -    private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 289 +    @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                             
 290      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 291      private int mPendingAddWidgetId = -1;                                                                         
 292                                                                                                                    
 293      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 294                                                                                                                    
 295 -    private FolderInfo mFolderInfo;                                                                               
 296 -                                                                                                                  
 297      private Hotseat mHotseat;                                                                                     
 298      private ViewGroup mOverviewPanel;                                                                             
 299                                                                                                                    
 300      private View mAllAppsButton;                                                                                  
 301                                                                                                                    
 302      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 303 -    private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 304 -    private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 305 +                                                                                                                  
 306 +    // Main container view for the all apps screen.                                                               
 307 +    @Thunk AllAppsContainerView mAppsView;                                                                        
 308 +                                                                                                                  
 309 +    // Main container view and the model for the widget tray screen.                                              
 310 +    @Thunk WidgetsContainerView mWidgetsView;                                                                     
 311 +    @Thunk WidgetsModel mWidgetsModel;                                                                            
 312 +                                                                                                                  
 313      private boolean mAutoAdvanceRunning = false;                                                                  
 314      private AppWidgetHostView mQsb;                                                                               
 315                                                                                                                    
 316      private Bundle mSavedState;                                                                                   
 317      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 318      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 319      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 320      private State mOnResumeState = State.NONE;                                                                    
 321                                                                                                                    
 322      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 323                                                                                                                    
 324 -    private boolean mWorkspaceLoading = true;                                                                     
 325 +    @Thunk boolean mWorkspaceLoading = true;                                                                      
 326                                                                                                                    
 327      private boolean mPaused = true;                                                                               
 328      private boolean mRestoring;                                                                                   
 329      private boolean mWaitingForResult;                                                                            
 330      private boolean mOnResumeNeedsLoad;                                                                           
 331                                                                                                                    
 332      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 333      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 334                                                                                                                    
 335      private Bundle mSavedInstanceState;                                                                           
 336                                                                                                                    
 337      private LauncherModel mModel;                                                                                 
 338      private IconCache mIconCache;                                                                                 
 339 -    private boolean mUserPresent = true;                                                                          
 340 +    @Thunk boolean mUserPresent = true;                                                                           
 341      private boolean mVisible = false;                                                                             
 342      private boolean mHasFocus = false;                                                                            
 343      private boolean mAttached = false;                                                                            
 344                                                                                                                    
 345 -    private static LocaleConfiguration sLocaleConfiguration = null;                                               
 346 -                                                                                                                  
 347 -    private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 348 +    @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                                
 349 +                                                                                                                  
 350 +    private static LongArrayMap<FolderInfo> sFolders = new LongArrayMap<>();                                      
 351                                                                                                                    
 352      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 353 -                                                                                                                  
 354 -    public static final int BUILD_LAYER = 0;                                                                      
 355 -    public static final int BUILD_AND_SET_LAYER = 1;                                                              
 356                                                                                                                    
 357      // Related to the auto-advancing of widgets                                                                   
 358      private final int ADVANCE_MSG = 1;                                                                            
 359      private final int mAdvanceInterval = 20000;                                                                   
 360      private final int mAdvanceStagger = 250;                                                                      
 361      private long mAutoAdvanceSentTime;                                                                            
 362      private long mAutoAdvanceTimeLeft = -1;                                                                       
 363 -    private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 364 +    @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                               
 365          new HashMap<View, AppWidgetProviderInfo>();                                                               
 366                                                                                                                    
 367      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 368      // match the sensor state.                                                                                    
 369      private final int mRestoreScreenOrientationDelay = 500;                                                       
 370                                                                                                                    
 371 -    private Drawable mWorkspaceBackgroundDrawable;                                                                
 372 +    @Thunk Drawable mWorkspaceBackgroundDrawable;                                                                 
 373                                                                                                                    
 374      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 375      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 376                                                                                                                    
 377      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 378      static Date sDateStamp = new Date();                                                                          
 379      static DateFormat sDateFormat =                                                                               
 380              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 381      static long sRunStart = System.currentTimeMillis();                                                           
 382      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 383                                                                                                                    
 384      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 385      // it from the context.                                                                                       
 386      private SharedPreferences mSharedPrefs;                                                                       
 387                                                                                                                    
 388 -    private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 389 -                                                                                                                  
 390      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 391      // when we scroll to that page on resume.                                                                     
 392 -    private ImageView mFolderIconImageView;                                                                       
 393 +    @Thunk ImageView mFolderIconImageView;                                                                        
 394      private Bitmap mFolderIconBitmap;                                                                             
 395      private Canvas mFolderIconCanvas;                                                                             
 396      private Rect mRectForFolderAnimation = new Rect();                                                            
 397                                                                                                                    
 398 +    private DeviceProfile mDeviceProfile;                                                                         
 399 +                                                                                                                  
 400 +    // This is set to the view that launched the activity that navigated the user away from                       
 401 +    // launcher. Since there is no callback for when the activity has finished launching, enable                  
 402 +    // the press state and keep this reference to reset the press state when we return to launcher.               
 403      private BubbleTextView mWaitingForResume;                                                                     
 404                                                                                                                    
 405      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 406              new HashMap<String, CustomAppWidget>();                                                               
 407                                                                                                                    
 408      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 409      static {                                                                                                      
 410          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 411              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                
 412          }                                                                                                         
 413      }                                                                                                             
 414                                                                                                                    
 415 -    private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 416 +    // TODO: remove this field and call method directly when Launcher3 can depend on M APIs                       
 417 +    private static Method sClipRevealMethod = null;                                                               
 418 +    static {                                                                                                      
 419 +        Class<?> activityOptionsClass = ActivityOptions.class;                                                    
 420 +        try {                                                                                                     
 421 +            sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",                 
 422 +                    View.class, int.class, int.class, int.class, int.class);                                      
 423 +        } catch (Exception e) {                                                                                   
 424 +            // Earlier version                                                                                    
 425 +        }                                                                                                         
 426 +    }                                                                                                             
 427 +                                                                                                                  
 428 +    @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                                       
 429          public void run() {                                                                                       
 430              if (mWorkspace != null) {                                                                             
 431                  mWorkspace.buildPageHardwareLayers();                                                             
 432              }                                                                                                     
 433          }                                                                                                         
 434      };                                                                                                            
 435                                                                                                                    
 436      private static PendingAddArguments sPendingAddItem;                                                           
 437                                                                                                                    
 438 -    private static class PendingAddArguments {                                                                    
 439 +    @Thunk static class PendingAddArguments {                                                                     
 440          int requestCode;                                                                                          
 441          Intent intent;                                                                                            
 442          long container;                                                                                           
 443          long screenId;                                                                                            
 444          int cellX;                                                                                                
 445          int cellY;                                                                                                
 446          int appWidgetId;                                                                                          
 447      }                                                                                                             
 448                                                                                                                    
 449      private Stats mStats;                                                                                         
 450                                                                                                                    
 451      FocusIndicatorView mFocusHandler;                                                                             
 452                                                                                                                    
 453      @Override                                                                                                     
 454      protected void onCreate(Bundle savedInstanceState) {                                                          
 455          if (DEBUG_STRICT_MODE) {                                                                                  
 456              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 457                      .detectDiskReads()                                                                            
 458                      .detectDiskWrites()                                                                           
 459                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 460                      .penaltyLog()                                                                                 
 461                      .build());                                                                                    
 462              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 463                      .detectLeakedSqlLiteObjects()                                                                 
 464                      .detectLeakedClosableObjects()                                                                
 465                      .penaltyLog()                                                                                 
 466                      .penaltyDeath()                                                                               
 467                      .build());                                                                                    
 468          }                                                                                                         
 469                                                                                                                    
 470          if (mLauncherCallbacks != null) {                                                                         
 471              mLauncherCallbacks.preOnCreate();                                                                     
 472          }                                                                                                         
 473                                                                                                                    
 474          super.onCreate(savedInstanceState);                                                                       
 475                                                                                                                    
 476          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 477          LauncherAppState app = LauncherAppState.getInstance();                                                    
 478          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 479                                                                                                                    
 480 -        // Lazy-initialize the dynamic grid                                                                       
 481 -        DeviceProfile grid = app.initDynamicGrid(this);                                                           
 482 +        // Load configuration-specific DeviceProfile                                                              
 483 +        mDeviceProfile = getResources().getConfiguration().orientation                                            
 484 +                == Configuration.ORIENTATION_LANDSCAPE ?                                                          
 485 +                        app.getInvariantDeviceProfile().landscapeProfile                                          
 486 +                            : app.getInvariantDeviceProfile().portraitProfile;                                    
 487 +                                                                                                                  
 488 +        // TODO: Move this to icon cache.                                                                         
 489 +        Utilities.setIconSize(mDeviceProfile.iconSizePx);                                                         
 490                                                                                                                    
 491          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 492          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 493                  Context.MODE_PRIVATE);                                                                            
 494          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 495          mModel = app.setLauncher(this);                                                                           
 496          mIconCache = app.getIconCache();                                                                          
 497 -        mIconCache.flushInvalidIcons(grid);                                                                       
 498 +                                                                                                                  
 499          mDragController = new DragController(this);                                                               
 500          mInflater = getLayoutInflater();                                                                          
 501 +        mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                             
 502                                                                                                                    
 503          mStats = new Stats(this);                                                                                 
 504                                                                                                                    
 505          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 506                                                                                                                    
 507          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 508          mAppWidgetHost.startListening();                                                                          
 509                                                                                                                    
 510          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 511          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 512          // LauncherModel load.                                                                                    
 513          mPaused = false;                                                                                          
 514                                                                                                                    
 515          if (PROFILE_STARTUP) {                                                                                    
 516              android.os.Debug.startMethodTracing(                                                                  
 517                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 518          }                                                                                                         
 519                                                                                                                    
 520          checkForLocaleChange();                                                                                   
 521          setContentView(R.layout.launcher);                                                                        
 522                                                                                                                    
 523          setupViews();                                                                                             
 524 -        grid.layout(this);                                                                                        
 525 +        mDeviceProfile.layout(this);                                                                              
 526                                                                                                                    
 527          registerContentObservers();                                                                               
 528                                                                                                                    
 529          lockAllApps();                                                                                            
 530                                                                                                                    
 531          mSavedState = savedInstanceState;                                                                         
 532          restoreState(mSavedState);                                                                                
 533                                                                                                                    
 534          if (PROFILE_STARTUP) {                                                                                    
 535              android.os.Debug.stopMethodTracing();                                                                 
 536          }                                                                                                         
 537                                                                                                                    
 538          if (!mRestoring) {                                                                                        
 539              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 540                  // If the user leaves launcher, then we should just load items asynchronously when                
 541                  // they return.                                                                                   
 542 -                mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 543 +                mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                               
 544              } else {                                                                                              
 545                  // We only load the page synchronously if the user rotates (or triggers a                         
 546                  // configuration change) while launcher is in the foreground                                      
 547 -                mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 548 +                mModel.startLoader(mWorkspace.getRestorePage());                                                  
 549              }                                                                                                     
 550          }                                                                                                         
 551                                                                                                                    
 552          // For handling default keys                                                                              
 553          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 554          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 555                                                                                                                    
 556          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 557          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 558                                                                                                                    
 559          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 560          unlockScreenOrientation(true);                                                                            
 561                                                                                                                    
 562          if (mLauncherCallbacks != null) {                                                                         
 563              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 564              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 565                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 566                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 567                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 568                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 569                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 570              }                                                                                                     
 571          }                                                                                                         
 572                                                                                                                    
 573          if (shouldShowIntroScreen()) {                                                                            
 574              showIntroScreen();                                                                                    
 575          } else {                                                                                                  
 576              showFirstRunActivity();                                                                               
 577              showFirstRunClings();                                                                                 
 578          }                                                                                                         
 579      }                                                                                                             
 580                                                                                                                    
 581      private LauncherCallbacks mLauncherCallbacks;                                                                 
 582                                                                                                                    
 583      public void onPostCreate(Bundle savedInstanceState) {                                                         
 584          super.onPostCreate(savedInstanceState);                                                                   
 585          if (mLauncherCallbacks != null) {                                                                         
 586              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 587          }                                                                                                         
 588      }                                                                                                             
 589                                                                                                                    
 590      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 591          mLauncherCallbacks = callbacks;                                                                           
 592 +        mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                         
 593 +            @Override                                                                                             
 594 +            public void onAllAppsBoundsChanged(Rect bounds) {                                                     
 595 +                if (LOGD) {                                                                                       
 596 +                    Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);                                        
 597 +                }                                                                                                 
 598 +                mAppsView.setFixedBounds(bounds);                                                                 
 599 +                mWidgetsView.setFixedBounds(bounds);                                                              
 600 +            }                                                                                                     
 601 +                                                                                                                  
 602 +            @Override                                                                                             
 603 +            public void dismissAllApps() {                                                                        
 604 +                if (!DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                       
 605 +                    // Dismiss All Apps if we aren't already paused/invisible                                     
 606 +                    if (!mPaused) {                                                                               
 607 +                        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true,             
 608 +                                null /* onCompleteRunnable */, false /* notifyLauncherCallbacks */);              
 609 +                    }                                                                                             
 610 +                }                                                                                                 
 611 +            }                                                                                                     
 612 +        });                                                                                                       
 613          return true;                                                                                              
 614      }                                                                                                             
 615                                                                                                                    
 616      @Override                                                                                                     
 617      public void onLauncherProviderChange() {                                                                      
 618          if (mLauncherCallbacks != null) {                                                                         
 619              mLauncherCallbacks.onLauncherProviderChange();                                                        
 620          }                                                                                                         
 621      }                                                                                                             
 622                                                                                                                    
 623      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 624      protected boolean hasCustomContentToLeft() {                                                                  
 625          if (mLauncherCallbacks != null) {                                                                         
 626              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 627          }                                                                                                         
 628          return false;                                                                                             
 629      }                                                                                                             
 630                                                                                                                    
 631      /**                                                                                                           
 632       * To be overridden by subclasses to populate the custom content container and call                           
 633       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 634       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 635       */                                                                                                           
 636      protected void populateCustomContentContainer() {                                                             
 637          if (mLauncherCallbacks != null) {                                                                         
 638              mLauncherCallbacks.populateCustomContentContainer();                                                  
 639          }                                                                                                         
 640      }                                                                                                             
 641                                                                                                                    
 642      /**                                                                                                           
 643       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 644       * ensure the custom content page is added or removed if necessary.                                           
 645       */                                                                                                           
 646      protected void invalidateHasCustomContentToLeft() {                                                           
 647          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 648              // Not bound yet, wait for bindScreens to be called.                                                  
 649              return;                                                                                               
 650          }                                                                                                         
 651                                                                                                                    
 652          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 653              // Create the custom content page and call the subclass to populate it.                               
 654              mWorkspace.createCustomContentContainer();                                                            
 655              populateCustomContentContainer();                                                                     
 656          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 657              mWorkspace.removeCustomContentPage();                                                                 
 658          }                                                                                                         
 659      }                                                                                                             
 660                                                                                                                    
 661 -    private void checkForLocaleChange() {                                                                         
 662 +    @Thunk void checkForLocaleChange() {                                                                          
 663          if (sLocaleConfiguration == null) {                                                                       
 664              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 665                  @Override                                                                                         
 666                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 667                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 668                      readConfiguration(Launcher.this, localeConfiguration);                                        
 669                      return localeConfiguration;                                                                   
 670                  }                                                                                                 
 671                                                                                                                    
 672                  @Override                                                                                         
 673                  protected void onPostExecute(LocaleConfiguration result) {                                        
 674                      sLocaleConfiguration = result;                                                                
 675                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 676                  }                                                                                                 
 677              }.execute();                                                                                          
 678              return;                                                                                               
 679          }                                                                                                         
 680                                                                                                                    
 681          final Configuration configuration = getResources().getConfiguration();                                    
 682                                                                                                                    
 683          final String previousLocale = sLocaleConfiguration.locale;                                                
 684          final String locale = configuration.locale.toString();                                                    
 685                                                                                                                    
 686          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 687          final int mcc = configuration.mcc;                                                                        
 688                                                                                                                    
 689          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 690          final int mnc = configuration.mnc;                                                                        
 691                                                                                                                    
 692          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 693                                                                                                                    
 694          if (localeChanged) {                                                                                      
 695              sLocaleConfiguration.locale = locale;                                                                 
 696              sLocaleConfiguration.mcc = mcc;                                                                       
 697              sLocaleConfiguration.mnc = mnc;                                                                       
 698                                                                                                                    
 699              mIconCache.flush();                                                                                   
 700                                                                                                                    
 701              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 702              new AsyncTask<Void, Void, Void>() {                                                                   
 703                  public Void doInBackground(Void ... args) {                                                       
 704                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 705                      return null;                                                                                  
 706                  }                                                                                                 
 707              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 708          }                                                                                                         
 709      }                                                                                                             
 710                                                                                                                    
 711 -    private static class LocaleConfiguration {                                                                    
 712 +    @Thunk static class LocaleConfiguration {                                                                     
 713          public String locale;                                                                                     
 714          public int mcc = -1;                                                                                      
 715          public int mnc = -1;                                                                                      
 716      }                                                                                                             
 717                                                                                                                    
 718 -    private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 719 +    @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {                    
 720          DataInputStream in = null;                                                                                
 721          try {                                                                                                     
 722              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 723              configuration.locale = in.readUTF();                                                                  
 724              configuration.mcc = in.readInt();                                                                     
 725              configuration.mnc = in.readInt();                                                                     
 726          } catch (FileNotFoundException e) {                                                                       
 727              // Ignore                                                                                             
 728          } catch (IOException e) {                                                                                 
 729              // Ignore                                                                                             
 730          } finally {                                                                                               
 731              if (in != null) {                                                                                     
 732                  try {                                                                                             
 733                      in.close();                                                                                   
 734                  } catch (IOException e) {                                                                         
 735                      // Ignore                                                                                     
 736                  }                                                                                                 
 737              }                                                                                                     
 738          }                                                                                                         
 739      }                                                                                                             
 740                                                                                                                    
 741 -    private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 742 +    @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {                   
 743          DataOutputStream out = null;                                                                              
 744          try {                                                                                                     
 745              out = new DataOutputStream(context.openFileOutput(                                                    
 746                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 747              out.writeUTF(configuration.locale);                                                                   
 748              out.writeInt(configuration.mcc);                                                                      
 749              out.writeInt(configuration.mnc);                                                                      
 750              out.flush();                                                                                          
 751          } catch (FileNotFoundException e) {                                                                       
 752              // Ignore                                                                                             
 753          } catch (IOException e) {                                                                                 
 754              //noinspection ResultOfMethodCallIgnored                                                              
 755              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 756          } finally {                                                                                               
 757              if (out != null) {                                                                                    
 758                  try {                                                                                             
 759                      out.close();                                                                                  
 760                  } catch (IOException e) {                                                                         
 761                      // Ignore                                                                                     
 762                  }                                                                                                 
 763              }                                                                                                     
 764          }                                                                                                         
 765      }                                                                                                             
 766                                                                                                                    
 767      public Stats getStats() {                                                                                     
 768          return mStats;                                                                                            
 769      }                                                                                                             
 770                                                                                                                    
 771      public LayoutInflater getInflater() {                                                                         
 772          return mInflater;                                                                                         
 773      }                                                                                                             
 774                                                                                                                    
 775 -    boolean isDraggingEnabled() {                                                                                 
 776 +    public boolean isDraggingEnabled() {                                                                          
 777          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 778          // that is subsequently removed from the workspace in startBinding().                                     
 779          return !mModel.isLoadingWorkspace();                                                                      
 780      }                                                                                                             
 781                                                                                                                    
 782      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 783      public static int generateViewId() {                                                                          
 784          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 785              return View.generateViewId();                                                                         
 786          } else {                                                                                                  
 787              // View.generateViewId() is not available. The following fallback logic is a copy                     
 788              // of its implementation.                                                                             
 789              for (;;) {                                                                                            
 790                  final int result = sNextGeneratedId.get();                                                        
 791                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 792                  int newValue = result + 1;                                                                        
 793                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 794                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 795                      return result;                                                                                
 796                  }                                                                                                 
 797              }                                                                                                     
 798          }                                                                                                         
 799      }                                                                                                             
 800                                                                                                                    
 801      public int getViewIdForItem(ItemInfo info) {                                                                  
 802          // This cast is safe given the > 2B range for int.                                                        
 803          int itemId = (int) info.id;                                                                               
 804          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 805              return mItemIdToViewId.get(itemId);                                                                   
 806          }                                                                                                         
 807          int viewId = generateViewId();                                                                            
 808          mItemIdToViewId.put(itemId, viewId);                                                                      
 809          return viewId;                                                                                            
 810      }                                                                                                             
 811                                                                                                                    
 812      /**                                                                                                           
 813       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 814       * a configuration step, this allows the proper animations to run after other transitions.                    
 815       */                                                                                                           
 816      private long completeAdd(PendingAddArguments args) {                                                          
 817          long screenId = args.screenId;                                                                            
 818          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 819              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 820              // that the drop page actually exists.                                                                
 821              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 822          }                                                                                                         
 823                                                                                                                    
 824          switch (args.requestCode) {                                                                               
 825              case REQUEST_CREATE_SHORTCUT:                                                                         
 826                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 827                          args.cellY);                                                                              
 828                  break;                                                                                            
 829              case REQUEST_CREATE_APPWIDGET:                                                                        
 830                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 831                  break;                                                                                            
 832              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 833                  completeRestoreAppWidget(args.appWidgetId);                                                       
 834                  break;                                                                                            
 835          }                                                                                                         
 836          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 837          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 838          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 839          resetAddInfo();                                                                                           
 840          return screenId;                                                                                          
 841      }                                                                                                             
 842                                                                                                                    
 843      private void handleActivityResult(                                                                            
 844              final int requestCode, final int resultCode, final Intent data) {                                     
 845          // Reset the startActivity waiting flag                                                                   
 846          setWaitingForResult(false);                                                                               
 847          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 848          mPendingAddWidgetId = -1;                                                                                 
 849                                                                                                                    
 850          Runnable exitSpringLoaded = new Runnable() {                                                              
 851              @Override                                                                                             
 852              public void run() {                                                                                   
 853                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 854                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 855              }                                                                                                     
 856          };                                                                                                        
 857                                                                                                                    
 858          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 859              final int appWidgetId = data != null ?                                                                
 860                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 861              if (resultCode == RESULT_CANCELED) {                                                                  
 862                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 863                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 864                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 865              } else if (resultCode == RESULT_OK) {                                                                 
 866                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 867                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 868              }                                                                                                     
 869              return;                                                                                               
 870          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 871              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 872 -                mWorkspace.exitOverviewMode(false);                                                               
 873 +                showWorkspace(false);                                                                             
 874              }                                                                                                     
 875              return;                                                                                               
 876          }                                                                                                         
 877                                                                                                                    
 878          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 879                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 880                                                                                                                    
 881          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 882          // We have special handling for widgets                                                                   
 883          if (isWidgetDrop) {                                                                                       
 884              final int appWidgetId;                                                                                
 885              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 886                      : -1;                                                                                         
 887              if (widgetId < 0) {                                                                                   
 888                  appWidgetId = pendingAddWidgetId;                                                                 
 889              } else {                                                                                              
 890                  appWidgetId = widgetId;                                                                           
 891              }                                                                                                     
 892                                                                                                                    
 893              final int result;                                                                                     
 894              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 895                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 896                          "returned from the widget configuration activity.");                                      
 897                  result = RESULT_CANCELED;                                                                         
 898                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 899                  final Runnable onComplete = new Runnable() {                                                      
 900                      @Override                                                                                     
 901                      public void run() {                                                                           
 902                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 903                      }                                                                                             
 904                  };                                                                                                
 905                  if (workspaceLocked) {                                                                            
 906                      // No need to remove the empty screen if we're mid-binding, as the                            
 907                      // the bind will not add the empty screen.                                                    
 908                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 909                  } else {                                                                                          
 910                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 911                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 912                  }                                                                                                 
 913              } else {                                                                                              
 914                  if (!workspaceLocked) {                                                                           
 915                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 916                          // When the screen id represents an actual screen (as opposed to a rank)                  
 917                          // we make sure that the drop page actually exists.                                       
 918                          mPendingAddInfo.screenId =                                                                
 919                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 920                      }                                                                                             
 921                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 922                                                                                                                    
 923                      dropLayout.setDropPending(true);                                                              
 924                      final Runnable onComplete = new Runnable() {                                                  
 925                          @Override                                                                                 
 926                          public void run() {                                                                       
 927                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 928                              dropLayout.setDropPending(false);                                                     
 929                          }                                                                                         
 930                      };                                                                                            
 931                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 932                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 933                  } else {                                                                                          
 934                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 935                              mPendingAddInfo);                                                                     
 936                      sPendingAddItem = args;                                                                       
 937                  }                                                                                                 
 938              }                                                                                                     
 939              return;                                                                                               
 940          }                                                                                                         
 941                                                                                                                    
 942          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 943              if (resultCode == RESULT_OK) {                                                                        
 944                  // Update the widget view.                                                                        
 945                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 946                          pendingAddWidgetId, mPendingAddInfo);                                                     
 947                  if (workspaceLocked) {                                                                            
 948                      sPendingAddItem = args;                                                                       
 949                  } else {                                                                                          
 950                      completeAdd(args);                                                                            
 951                  }                                                                                                 
 952              }                                                                                                     
 953              // Leave the widget in the pending state if the user canceled the configure.                          
 954              return;                                                                                               
 955          }                                                                                                         
 956                                                                                                                    
 957          // The pattern used here is that a user PICKs a specific application,                                     
 958          // which, depending on the target, might need to CREATE the actual target.                                
 959                                                                                                                    
 960          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 961          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 962          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 963              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 964                      mPendingAddInfo);                                                                             
 965              if (isWorkspaceLocked()) {                                                                            
 966                  sPendingAddItem = args;                                                                           
 967              } else {                                                                                              
 968                  completeAdd(args);                                                                                
 969                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 970                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 971              }                                                                                                     
 972          } else if (resultCode == RESULT_CANCELED) {                                                               
 973              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 974                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 975          }                                                                                                         
 976          mDragLayer.clearAnimatedView();                                                                           
 977                                                                                                                    
 978      }                                                                                                             
 979                                                                                                                    
 980      @Override                                                                                                     
 981      protected void onActivityResult(                                                                              
 982              final int requestCode, final int resultCode, final Intent data) {                                     
 983          handleActivityResult(requestCode, resultCode, data);                                                      
 984          if (mLauncherCallbacks != null) {                                                                         
 985              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 986          }                                                                                                         
 987      }                                                                                                             
 988                                                                                                                    
 989      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 990              appWidgetId, ItemInfo info) {                                                                         
 991          PendingAddArguments args = new PendingAddArguments();                                                     
 992          args.requestCode = requestCode;                                                                           
 993          args.intent = data;                                                                                       
 994          args.container = info.container;                                                                          
 995          args.screenId = info.screenId;                                                                            
 996          args.cellX = info.cellX;                                                                                  
 997          args.cellY = info.cellY;                                                                                  
 998          args.appWidgetId = appWidgetId;                                                                           
 999          return args;                                                                                              
1000      }                                                                                                             
1001                                                                                                                    
1002      /**                                                                                                           
1003       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
1004       *                                                                                                            
1005       * @param screenId the screen id to check                                                                     
1006       * @return the new screen, or screenId if it exists                                                           
1007       */                                                                                                           
1008      private long ensurePendingDropLayoutExists(long screenId) {                                                   
1009          CellLayout dropLayout =                                                                                   
1010                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
1011          if (dropLayout == null) {                                                                                 
1012              // it's possible that the add screen was removed because it was                                       
1013              // empty and a re-bind occurred                                                                       
1014              mWorkspace.addExtraEmptyScreen();                                                                     
1015              return mWorkspace.commitExtraEmptyScreen();                                                           
1016          } else {                                                                                                  
1017              return screenId;                                                                                      
1018          }                                                                                                         
1019      }                                                                                                             
1020                                                                                                                    
1021 -    private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
1022 +    @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                         
1023          CellLayout cellLayout =                                                                                   
1024                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
1025          Runnable onCompleteRunnable = null;                                                                       
1026          int animationType = 0;                                                                                    
1027                                                                                                                    
1028          AppWidgetHostView boundWidget = null;                                                                     
1029          if (resultCode == RESULT_OK) {                                                                            
1030              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
1031              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
1032                      mPendingAddWidgetInfo);                                                                       
1033              boundWidget = layout;                                                                                 
1034              onCompleteRunnable = new Runnable() {                                                                 
1035                  @Override                                                                                         
1036                  public void run() {                                                                               
1037                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
1038                              mPendingAddInfo.screenId, layout, null);                                              
1039                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
1040                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
1041                  }                                                                                                 
1042              };                                                                                                    
1043          } else if (resultCode == RESULT_CANCELED) {                                                               
1044              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
1045              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
1046          }                                                                                                         
1047          if (mDragLayer.getAnimatedView() != null) {                                                               
1048              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
1049                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
1050                      animationType, boundWidget, true);                                                            
1051          } else if (onCompleteRunnable != null) {                                                                  
1052              // The animated view may be null in the case of a rotation during widget configuration                
1053              onCompleteRunnable.run();                                                                             
1054          }                                                                                                         
1055      }                                                                                                             
1056                                                                                                                    
1057      @Override                                                                                                     
1058      protected void onStop() {                                                                                     
1059          super.onStop();                                                                                           
1060          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
1061                                                                                                                    
1062          if (mLauncherCallbacks != null) {                                                                         
1063              mLauncherCallbacks.onStop();                                                                          
1064          }                                                                                                         
1065      }                                                                                                             
1066                                                                                                                    
1067      @Override                                                                                                     
1068      protected void onStart() {                                                                                    
1069          super.onStart();                                                                                          
1070          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
1071                                                                                                                    
1072          if (mLauncherCallbacks != null) {                                                                         
1073              mLauncherCallbacks.onStart();                                                                         
1074          }                                                                                                         
1075      }                                                                                                             
1076                                                                                                                    
1077      @Override                                                                                                     
1078      protected void onResume() {                                                                                   
1079          long startTime = 0;                                                                                       
1080          if (DEBUG_RESUME_TIME) {                                                                                  
1081              startTime = System.currentTimeMillis();                                                               
1082              Log.v(TAG, "Launcher.onResume()");                                                                    
1083          }                                                                                                         
1084                                                                                                                    
1085          if (mLauncherCallbacks != null) {                                                                         
1086              mLauncherCallbacks.preOnResume();                                                                     
1087          }                                                                                                         
1088                                                                                                                    
1089          super.onResume();                                                                                         
1090                                                                                                                    
1091          // Restore the previous launcher state                                                                    
1092          if (mOnResumeState == State.WORKSPACE) {                                                                  
1093              showWorkspace(false);                                                                                 
1094 -        } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
1095 -            showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
1096 +        } else if (mOnResumeState == State.APPS) {                                                                
1097 +            boolean launchedFromApp = (mWaitingForResume != null);                                                
1098 +            // Don't update the predicted apps if the user is returning to launcher in the apps                   
1099 +            // view after launching an app, as they may be depending on the UI to be static to                    
1100 +            // switch to another app, otherwise, if it was                                                        
1101 +            showAppsView(false /* animated */, false /* resetListToTop */,                                        
1102 +                    !launchedFromApp /* updatePredictedApps */);                                                  
1103 +        } else if (mOnResumeState == State.WIDGETS) {                                                             
1104 +            showWidgetsView(false, false);                                                                        
1105          }                                                                                                         
1106          mOnResumeState = State.NONE;                                                                              
1107                                                                                                                    
1108 -        // Background was set to gradient in onPause(), restore to black if in all apps.                          
1109 -        setWorkspaceBackground(mState == State.WORKSPACE);                                                        
1110 +        // Restore the apps state if we are in all apps                                                           
1111 +        if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                      
1112 +            // Otherwise, notify the callbacks if we are in all apps mode                                         
1113 +            if (mState == State.APPS) {                                                                           
1114 +                if (mLauncherCallbacks != null) {                                                                 
1115 +                    mLauncherCallbacks.onAllAppsShown();                                                          
1116 +                }                                                                                                 
1117 +            }                                                                                                     
1118 +        }                                                                                                         
1119 +                                                                                                                  
1120 +        // Background was set to gradient in onPause(), restore to transparent if in all apps.                    
1121 +        setWorkspaceBackground(mState == State.WORKSPACE ? WORKSPACE_BACKGROUND_TRANSPARENT                       
1122 +                : WORKSPACE_BACKGROUND_GRADIENT);                                                                 
1123                                                                                                                    
1124          mPaused = false;                                                                                          
1125          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1126              setWorkspaceLoading(true);                                                                            
1127 -            mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1128 +            mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);                                                   
1129              mRestoring = false;                                                                                   
1130              mOnResumeNeedsLoad = false;                                                                           
1131          }                                                                                                         
1132          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1133              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1134              // execute them here                                                                                  
1135              long startTimeCallbacks = 0;                                                                          
1136              if (DEBUG_RESUME_TIME) {                                                                              
1137                  startTimeCallbacks = System.currentTimeMillis();                                                  
1138              }                                                                                                     
1139                                                                                                                    
1140 -            if (mAppsCustomizeContent != null) {                                                                  
1141 -                mAppsCustomizeContent.setBulkBind(true);                                                          
1142 -            }                                                                                                     
1143              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1144                  mBindOnResumeCallbacks.get(i).run();                                                              
1145 -            }                                                                                                     
1146 -            if (mAppsCustomizeContent != null) {                                                                  
1147 -                mAppsCustomizeContent.setBulkBind(false);                                                         
1148              }                                                                                                     
1149              mBindOnResumeCallbacks.clear();                                                                       
1150              if (DEBUG_RESUME_TIME) {                                                                              
1151                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1152                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1153              }                                                                                                     
1154          }                                                                                                         
1155          if (mOnResumeCallbacks.size() > 0) {                                                                      
1156              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1157                  mOnResumeCallbacks.get(i).run();                                                                  
1158              }                                                                                                     
1159              mOnResumeCallbacks.clear();                                                                           
1160          }                                                                                                         
1161                                                                                                                    
1162          // Reset the pressed state of icons that were locked in the press state while activities                  
1163          // were launching                                                                                         
1164          if (mWaitingForResume != null) {                                                                          
1165              // Resets the previous workspace icon press state                                                     
1166              mWaitingForResume.setStayPressed(false);                                                              
1167          }                                                                                                         
1168                                                                                                                    
1169          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1170          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1171          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1172          // orientation.                                                                                           
1173          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1174 -                                                                                                                  
1175 -        // Process any items that were added while Launcher was away.                                             
1176 -        InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1177 +        reinflateQSBIfNecessary();                                                                                
1178                                                                                                                    
1179          if (DEBUG_RESUME_TIME) {                                                                                  
1180              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1181          }                                                                                                         
1182                                                                                                                    
1183          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1184              // If we are resuming and the custom content is the current page, we call onShow().                   
1185              // It is also poassible that onShow will instead be called slightly after first layout                
1186              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1187              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1188                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1189              }                                                                                                     
1190          }                                                                                                         
1191 -        mWorkspace.updateInteractionForState();                                                                   
1192 +        updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());                                         
1193          mWorkspace.onResume();                                                                                    
1194                                                                                                                    
1195 -        PackageInstallerCompat.getInstance(this).onResume();                                                      
1196 +        if (!isWorkspaceLoading()) {                                                                              
1197 +            // Process any items that were added while Launcher was away.                                         
1198 +            InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                            
1199 +        }                                                                                                         
1200                                                                                                                    
1201          if (mLauncherCallbacks != null) {                                                                         
1202              mLauncherCallbacks.onResume();                                                                        
1203          }                                                                                                         
1204      }                                                                                                             
1205                                                                                                                    
1206      @Override                                                                                                     
1207      protected void onPause() {                                                                                    
1208          // Ensure that items added to Launcher are queued until Launcher returns                                  
1209          InstallShortcutReceiver.enableInstallQueue();                                                             
1210 -        PackageInstallerCompat.getInstance(this).onPause();                                                       
1211                                                                                                                    
1212          super.onPause();                                                                                          
1213          mPaused = true;                                                                                           
1214          mDragController.cancelDrag();                                                                             
1215          mDragController.resetLastGestureUpTime();                                                                 
1216                                                                                                                    
1217          // We call onHide() aggressively. The custom content callbacks should be able to                          
1218          // debounce excess onHide calls.                                                                          
1219          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1220              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1221          }                                                                                                         
1222                                                                                                                    
1223          if (mLauncherCallbacks != null) {                                                                         
1224              mLauncherCallbacks.onPause();                                                                         
1225          }                                                                                                         
1226      }                                                                                                             
1227                                                                                                                    
1228      public interface CustomContentCallbacks {                                                                     
1229          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1230          // by a onResume or by scrolling otherwise.                                                               
1231          public void onShow(boolean fromResume);                                                                   
1232                                                                                                                    
1233          // Custom content is completely hidden                                                                    
1234          public void onHide();                                                                                     
1235                                                                                                                    
1236          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1237          public void onScrollProgressChanged(float progress);                                                      
1238                                                                                                                    
1239          // Indicates whether the user is allowed to scroll away from the custom content.                          
1240          boolean isScrollingAllowed();                                                                             
1241      }                                                                                                             
1242                                                                                                                    
1243      public interface LauncherOverlay {                                                                            
1244                                                                                                                    
1245          /**                                                                                                       
1246           * Touch interaction leading to overscroll has begun                                                      
1247           */                                                                                                       
1248          public void onScrollInteractionBegin();                                                                   
1249                                                                                                                    
1250          /**                                                                                                       
1251           * Touch interaction related to overscroll has ended                                                      
1252           */                                                                                                       
1253          public void onScrollInteractionEnd();                                                                     
1254                                                                                                                    
1255          /**                                                                                                       
1256           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1257           * screen (or in the case of RTL, the rightmost screen).                                                  
1258           */                                                                                                       
1259          public void onScrollChange(int progress, boolean rtl);                                                    
1260                                                                                                                    
1261          /**                                                                                                       
1262           * Screen has stopped scrolling                                                                           
1263           */                                                                                                       
1264          public void onScrollSettled();                                                                            
1265                                                                                                                    
1266          /**                                                                                                       
1267           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1268           * to exit fully immersive mode.                                                                          
1269           */                                                                                                       
1270          public void forceExitFullImmersion();                                                                     
1271 +    }                                                                                                             
1272 +                                                                                                                  
1273 +    public interface LauncherAppsCallbacks {                                                                      
1274 +        /**                                                                                                       
1275 +         * Updates launcher to the available space that AllApps can take so as not to overlap with                
1276 +         * any other views.                                                                                       
1277 +         */                                                                                                       
1278 +        public void onAllAppsBoundsChanged(Rect bounds);                                                          
1279 +                                                                                                                  
1280 +        /**                                                                                                       
1281 +         * Called to dismiss all apps if it is showing.                                                           
1282 +         */                                                                                                       
1283 +        public void dismissAllApps();                                                                             
1284      }                                                                                                             
1285                                                                                                                    
1286      public interface LauncherOverlayCallbacks {                                                                   
1287          /**                                                                                                       
1288           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1289           * however it doesn't modify any state within the launcher.                                               
1290           */                                                                                                       
1291          public boolean canEnterFullImmersion();                                                                   
1292                                                                                                                    
1293          /**                                                                                                       
1294           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1295           * eg. by occupying the full screen and handling all touch events.                                        
1296           *                                                                                                        
1297           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1298           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1299           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1300           *                                                                                                        
1301           */                                                                                                       
1302          public boolean enterFullImmersion();                                                                      
1303                                                                                                                    
1304          /**                                                                                                       
1305           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1306           * full control over UI and state.                                                                        
1307           */                                                                                                       
1308          public void exitFullImmersion();                                                                          
1309      }                                                                                                             
1310                                                                                                                    
1311      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1312                                                                                                                    
1313          @Override                                                                                                 
1314          public boolean canEnterFullImmersion() {                                                                  
1315              return mState == State.WORKSPACE;                                                                     
1316          }                                                                                                         
1317                                                                                                                    
1318          @Override                                                                                                 
1319          public boolean enterFullImmersion() {                                                                     
1320              if (mState == State.WORKSPACE) {                                                                      
1321                  // When fully immersed, disregard any touches which fall through.                                 
1322                  mDragLayer.setBlockTouch(true);                                                                   
1323                  return true;                                                                                      
1324              }                                                                                                     
1325              return false;                                                                                         
1326          }                                                                                                         
1327                                                                                                                    
1328          @Override                                                                                                 
1329          public void exitFullImmersion() {                                                                         
1330              mDragLayer.setBlockTouch(false);                                                                      
1331          }                                                                                                         
1332      }                                                                                                             
1333                                                                                                                    
1334      protected boolean hasSettings() {                                                                             
1335          if (mLauncherCallbacks != null) {                                                                         
1336              return mLauncherCallbacks.hasSettings();                                                              
1337          }                                                                                                         
1338          return false;                                                                                             
1339      }                                                                                                             
1340                                                                                                                    
1341 -                                                                                                                  
1342      public void addToCustomContentPage(View customContent,                                                        
1343              CustomContentCallbacks callbacks, String description) {                                               
1344          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1345      }                                                                                                             
1346                                                                                                                    
1347      // The custom content needs to offset its content to account for the QSB                                      
1348      public int getTopOffsetForCustomContent() {                                                                   
1349          return mWorkspace.getPaddingTop();                                                                        
1350      }                                                                                                             
1351                                                                                                                    
1352      @Override                                                                                                     
1353      public Object onRetainNonConfigurationInstance() {                                                            
1354          // Flag the loader to stop early before switching                                                         
1355          if (mModel.isCurrentCallbacks(this)) {                                                                    
1356              mModel.stopLoader();                                                                                  
1357          }                                                                                                         
1358 -        if (mAppsCustomizeContent != null) {                                                                      
1359 -            mAppsCustomizeContent.surrender();                                                                    
1360 -        }                                                                                                         
1361 +        //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                                     
1362 +                                                                                                                  
1363          return Boolean.TRUE;                                                                                      
1364      }                                                                                                             
1365                                                                                                                    
1366      // We can't hide the IME if it was forced open.  So don't bother                                              
1367      @Override                                                                                                     
1368      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1369          super.onWindowFocusChanged(hasFocus);                                                                     
1370          mHasFocus = hasFocus;                                                                                     
1371                                                                                                                    
1372          if (mLauncherCallbacks != null) {                                                                         
1373              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1374          }                                                                                                         
1375      }                                                                                                             
1376                                                                                                                    
1377      private boolean acceptFilter() {                                                                              
1378          final InputMethodManager inputManager = (InputMethodManager)                                              
1379                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1380          return !inputManager.isFullscreenMode();                                                                  
1381      }                                                                                                             
1382                                                                                                                    
1383      @Override                                                                                                     
1384      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1385          final int uniChar = event.getUnicodeChar();                                                               
1386          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1387          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1388          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1389              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1390                      keyCode, event);                                                                              
1391              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1392                  // something usable has been typed - start a search                                               
1393                  // the typed text will be retrieved and cleared by                                                
1394                  // showSearchDialog()                                                                             
1395                  // If there are multiple keystrokes before the search dialog takes focus,                         
1396                  // onSearchRequested() will be called for every keystroke,                                        
1397                  // but it is idempotent, so it's fine.                                                            
1398                  return onSearchRequested();                                                                       
1399              }                                                                                                     
1400          }                                                                                                         
1401                                                                                                                    
1402          // Eat the long press event so the keyboard doesn't come up.                                              
1403          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1404              return true;                                                                                          
1405          }                                                                                                         
1406                                                                                                                    
1407          return handled;                                                                                           
1408      }                                                                                                             
1409                                                                                                                    
1410      private String getTypedText() {                                                                               
1411          return mDefaultKeySsb.toString();                                                                         
1412      }                                                                                                             
1413                                                                                                                    
1414      private void clearTypedText() {                                                                               
1415          mDefaultKeySsb.clear();                                                                                   
1416          mDefaultKeySsb.clearSpans();                                                                              
1417          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1418      }                                                                                                             
1419                                                                                                                    
1420      /**                                                                                                           
1421       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1422       * State                                                                                                      
1423       */                                                                                                           
1424      private static State intToState(int stateOrdinal) {                                                           
1425          State state = State.WORKSPACE;                                                                            
1426          final State[] stateValues = State.values();                                                               
1427          for (int i = 0; i < stateValues.length; i++) {                                                            
1428              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1429                  state = stateValues[i];                                                                           
1430                  break;                                                                                            
1431              }                                                                                                     
1432          }                                                                                                         
1433          return state;                                                                                             
1434      }                                                                                                             
1435                                                                                                                    
1436      /**                                                                                                           
1437       * Restores the previous state, if it exists.                                                                 
1438       *                                                                                                            
1439       * @param savedState The previous state.                                                                      
1440       */                                                                                                           
1441      @SuppressWarnings("unchecked")                                                                                
1442      private void restoreState(Bundle savedState) {                                                                
1443          if (savedState == null) {                                                                                 
1444              return;                                                                                               
1445          }                                                                                                         
1446                                                                                                                    
1447          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1448 -        if (state == State.APPS_CUSTOMIZE) {                                                                      
1449 -            mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1450 +        if (state == State.APPS || state == State.WIDGETS) {                                                      
1451 +            mOnResumeState = state;                                                                               
1452          }                                                                                                         
1453                                                                                                                    
1454          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1455                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1456          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1457              mWorkspace.setRestorePage(currentScreen);                                                             
1458          }                                                                                                         
1459                                                                                                                    
1460          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1461          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1462                                                                                                                    
1463          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1464              mPendingAddInfo.container = pendingAddContainer;                                                      
1465              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1466              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1467              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1468              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1469              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1470              AppWidgetProviderInfo info = savedState.getParcelable(                                                
1471                      RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                                       
1472              mPendingAddWidgetInfo = info == null ?                                                                
1473                      null : LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                            
1474                                                                                                                    
1475              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1476              setWaitingForResult(true);                                                                            
1477              mRestoring = true;                                                                                    
1478          }                                                                                                         
1479                                                                                                                    
1480 -        boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1481 -        if (renameFolder) {                                                                                       
1482 -            long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1483 -            mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1484 -            mRestoring = true;                                                                                    
1485 -        }                                                                                                         
1486 -                                                                                                                  
1487 -        // Restore the AppsCustomize tab                                                                          
1488 -        if (mAppsCustomizeTabHost != null) {                                                                      
1489 -            String curTab = savedState.getString("apps_customize_currentTab");                                    
1490 -            if (curTab != null) {                                                                                 
1491 -                mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1492 -                        mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1493 -                mAppsCustomizeContent.loadAssociatedPages(                                                        
1494 -                        mAppsCustomizeContent.getCurrentPage());                                                  
1495 -            }                                                                                                     
1496 -                                                                                                                  
1497 -            int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1498 -            mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1499 -        }                                                                                                         
1500          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1501                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1502      }                                                                                                             
1503                                                                                                                    
1504      /**                                                                                                           
1505       * Finds all the views we need and configure them properly.                                                   
1506       */                                                                                                           
1507      private void setupViews() {                                                                                   
1508          final DragController dragController = mDragController;                                                    
1509                                                                                                                    
1510          mLauncherView = findViewById(R.id.launcher);                                                              
1511          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1512          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1513          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1514          mWorkspace.setPageSwitchListener(this);                                                                   
1515          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1516                                                                                                                    
1517          mLauncherView.setSystemUiVisibility(                                                                      
1518                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1519          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1520                                                                                                                    
1521          // Setup the drag layer                                                                                   
1522          mDragLayer.setup(this, dragController);                                                                   
1523                                                                                                                    
1524          // Setup the hotseat                                                                                      
1525          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1526          if (mHotseat != null) {                                                                                   
1527 -            mHotseat.setup(this);                                                                                 
1528              mHotseat.setOnLongClickListener(this);                                                                
1529          }                                                                                                         
1530                                                                                                                    
1531          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1532          View widgetButton = findViewById(R.id.widget_button);                                                     
1533          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1534              @Override                                                                                             
1535              public void onClick(View arg0) {                                                                      
1536                  if (!mWorkspace.isSwitchingState()) {                                                             
1537                      onClickAddWidgetButton(arg0);                                                                 
1538                  }                                                                                                 
1539              }                                                                                                     
1540          });                                                                                                       
1541          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1542                                                                                                                    
1543          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1544          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1545              @Override                                                                                             
1546              public void onClick(View arg0) {                                                                      
1547                  if (!mWorkspace.isSwitchingState()) {                                                             
1548                      onClickWallpaperPicker(arg0);                                                                 
1549                  }                                                                                                 
1550              }                                                                                                     
1551          });                                                                                                       
1552          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1553                                                                                                                    
1554          View settingsButton = findViewById(R.id.settings_button);                                                 
1555          if (hasSettings()) {                                                                                      
1556              settingsButton.setOnClickListener(new OnClickListener() {                                             
1557                  @Override                                                                                         
1558                  public void onClick(View arg0) {                                                                  
1559                      if (!mWorkspace.isSwitchingState()) {                                                         
1560                          onClickSettingsButton(arg0);                                                              
1561                      }                                                                                             
1562                  }                                                                                                 
1563              });                                                                                                   
1564              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1565          } else {                                                                                                  
1566              settingsButton.setVisibility(View.GONE);                                                              
1567          }                                                                                                         
1568                                                                                                                    
1569          mOverviewPanel.setAlpha(0f);                                                                              
1570                                                                                                                    
1571          // Setup the workspace                                                                                    
1572          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1573          mWorkspace.setOnLongClickListener(this);                                                                  
1574          mWorkspace.setup(dragController);                                                                         
1575          dragController.addDragListener(mWorkspace);                                                               
1576                                                                                                                    
1577          // Get the search/delete bar                                                                              
1578          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1579                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1580                                                                                                                    
1581 +        // Setup Apps                                                                                             
1582 +        mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);                                          
1583 +        if (isAllAppsSearchOverridden()) {                                                                        
1584 +            mAppsView.hideHeaderBar();                                                                            
1585 +        }                                                                                                         
1586 +                                                                                                                  
1587          // Setup AppsCustomize                                                                                    
1588 -        mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1589 -        mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1590 -                mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1591 -        mAppsCustomizeContent.setup(this, dragController);                                                        
1592 +        mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                                    
1593                                                                                                                    
1594          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1595          dragController.setDragScoller(mWorkspace);                                                                
1596          dragController.setScrollView(mDragLayer);                                                                 
1597          dragController.setMoveTarget(mWorkspace);                                                                 
1598          dragController.addDropTarget(mWorkspace);                                                                 
1599          if (mSearchDropTargetBar != null) {                                                                       
1600              mSearchDropTargetBar.setup(this, dragController);                                                     
1601 -            mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    
1602 +            mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                            
1603          }                                                                                                         
1604                                                                                                                    
1605          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1606              Log.v(TAG, "adding WeightWatcher");                                                                   
1607              mWeightWatcher = new WeightWatcher(this);                                                             
1608              mWeightWatcher.setAlpha(0.5f);                                                                        
1609              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1610                      new FrameLayout.LayoutParams(                                                                 
1611                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1612                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1613                              Gravity.BOTTOM)                                                                       
1614              );                                                                                                    
1615                                                                                                                    
1616              boolean show = shouldShowWeightWatcher();                                                             
1617              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1618          }                                                                                                         
1619      }                                                                                                             
1620                                                                                                                    
1621      /**                                                                                                           
1622       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1623       */                                                                                                           
1624      public void setAllAppsButton(View allAppsButton) {                                                            
1625          mAllAppsButton = allAppsButton;                                                                           
1626      }                                                                                                             
1627                                                                                                                    
1628      public View getAllAppsButton() {                                                                              
1629          return mAllAppsButton;                                                                                    
1630      }                                                                                                             
1631                                                                                                                    
1632      /**                                                                                                           
1633       * Creates a view representing a shortcut.                                                                    
1634       *                                                                                                            
1635       * @param info The data structure describing the shortcut.                                                    
1636 -     *                                                                                                            
1637 -     * @return A View inflated from R.layout.application.                                                         
1638       */                                                                                                           
1639      View createShortcut(ShortcutInfo info) {                                                                      
1640 -        return createShortcut(R.layout.application,                                                               
1641 -                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1642 +        return createShortcut((ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);              
1643      }                                                                                                             
1644                                                                                                                    
1645      /**                                                                                                           
1646       * Creates a view representing a shortcut inflated from the specified resource.                               
1647       *                                                                                                            
1648 -     * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1649       * @param parent The group the shortcut belongs to.                                                           
1650       * @param info The data structure describing the shortcut.                                                    
1651       *                                                                                                            
1652       * @return A View inflated from layoutResId.                                                                  
1653       */                                                                                                           
1654 -    public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1655 -        BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1656 -        favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1657 +    public View createShortcut(ViewGroup parent, ShortcutInfo info) {                                             
1658 +        BubbleTextView favorite = (BubbleTextView) mInflater.inflate(R.layout.app_icon,                           
1659 +                parent, false);                                                                                   
1660 +        favorite.applyFromShortcutInfo(info, mIconCache);                                                         
1661 +        favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);                                
1662          favorite.setOnClickListener(this);                                                                        
1663          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1664          return favorite;                                                                                          
1665      }                                                                                                             
1666                                                                                                                    
1667      /**                                                                                                           
1668       * Add a shortcut to the workspace.                                                                           
1669       *                                                                                                            
1670       * @param data The intent describing the shortcut.                                                            
1671       * @param cellInfo The position on screen where to create the shortcut.                                       
1672       */                                                                                                           
1673      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1674              int cellY) {                                                                                          
1675          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1676          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1677          CellLayout layout = getCellLayout(container, screenId);                                                   
1678                                                                                                                    
1679 -        boolean foundCellSpan = false;                                                                            
1680 -                                                                                                                  
1681 -        ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            
1682 +        ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(this, data);                               
1683          if (info == null) {                                                                                       
1684              return;                                                                                               
1685          }                                                                                                         
1686          final View view = createShortcut(info);                                                                   
1687                                                                                                                    
1688 +        boolean foundCellSpan = false;                                                                            
1689          // First we check if we already know the exact location where we want to add this item.                   
1690          if (cellX >= 0 && cellY >= 0) {                                                                           
1691              cellXY[0] = cellX;                                                                                    
1692              cellXY[1] = cellY;                                                                                    
1693              foundCellSpan = true;                                                                                 
1694                                                                                                                    
1695              // If appropriate, either create a folder or add to an existing folder                                
1696              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1697                      true, null,null)) {                                                                           
1698                  return;                                                                                           
1699              }                                                                                                     
1700              DragObject dragObject = new DragObject();                                                             
1701              dragObject.dragInfo = info;                                                                           
1702              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1703                      true)) {                                                                                      
1704                  return;                                                                                           
1705              }                                                                                                     
1706          } else if (touchXY != null) {                                                                             
1707              // when dragging and dropping, just find the closest free spot                                        
1708              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1709              foundCellSpan = (result != null);                                                                     
1710          } else {                                                                                                  
1711              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1712          }                                                                                                         
1713                                                                                                                    
1714          if (!foundCellSpan) {                                                                                     
1715              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1716              return;                                                                                               
1717          }                                                                                                         
1718                                                                                                                    
1719 -        LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1720 +        LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);                   
1721                                                                                                                    
1722          if (!mRestoring) {                                                                                        
1723              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1724                      isWorkspaceLocked());                                                                         
1725          }                                                                                                         
1726      }                                                                                                             
1727                                                                                                                    
1728 -    static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1729 -            int minHeight) {                                                                                      
1730 -        Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1731 +    private int[] getSpanForWidget(ComponentName component, int minWidth, int minHeight) {                        
1732 +        Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(this, component, null);                       
1733          // We want to account for the extra amount of padding that we are adding to the widget                    
1734          // to ensure that it gets the full amount of space that it has requested                                  
1735          int requiredWidth = minWidth + padding.left + padding.right;                                              
1736          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1737 -        return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1738 -    }                                                                                                             
1739 -                                                                                                                  
1740 -    static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1741 -        return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1742 -    }                                                                                                             
1743 -                                                                                                                  
1744 -    static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1745 -        return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1746 -    }                                                                                                             
1747 -                                                                                                                  
1748 -    static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1749 -        return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1750 -    }                                                                                                             
1751 -                                                                                                                  
1752 -    static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1753 -        return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1754 -                info.minResizeHeight);                                                                            
1755 +        return CellLayout.rectToCell(this, requiredWidth, requiredHeight, null);                                  
1756 +    }                                                                                                             
1757 +                                                                                                                  
1758 +    public int[] getSpanForWidget(AppWidgetProviderInfo info) {                                                   
1759 +        return getSpanForWidget(info.provider, info.minWidth, info.minHeight);                                    
1760 +    }                                                                                                             
1761 +                                                                                                                  
1762 +    public int[] getMinSpanForWidget(AppWidgetProviderInfo info) {                                                
1763 +        return getSpanForWidget(info.provider, info.minResizeWidth, info.minResizeHeight);                        
1764      }                                                                                                             
1765                                                                                                                    
1766      /**                                                                                                           
1767       * Add a widget to the workspace.                                                                             
1768       *                                                                                                            
1769       * @param appWidgetId The app widget id                                                                       
1770       */                                                                                                           
1771 -    private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             
1772 +    @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                              
1773              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1774                                                                                                                    
1775          ItemInfo info = mPendingAddInfo;                                                                          
1776          if (appWidgetInfo == null) {                                                                              
1777              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1778                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1779          }                                                                                                         
1780                                                                                                                    
1781          if (appWidgetInfo.isCustomWidget) {                                                                       
1782              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1783          }                                                                                                         
1784                                                                                                                    
1785          LauncherAppWidgetInfo launcherInfo;                                                                       
1786          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1787          launcherInfo.spanX = info.spanX;                                                                          
1788          launcherInfo.spanY = info.spanY;                                                                          
1789          launcherInfo.minSpanX = info.minSpanX;                                                                    
1790          launcherInfo.minSpanY = info.minSpanY;                                                                    
1791          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1792                                                                                                                    
1793          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1794 -                container, screenId, info.cellX, info.cellY, false);                                              
1795 +                container, screenId, info.cellX, info.cellY);                                                     
1796                                                                                                                    
1797          if (!mRestoring) {                                                                                        
1798              if (hostView == null) {                                                                               
1799                  // Perform actual inflation because we're live                                                    
1800                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1801                          appWidgetInfo);                                                                           
1802              } else {                                                                                              
1803                  // The AppWidgetHostView has already been inflated and instantiated                               
1804                  launcherInfo.hostView = hostView;                                                                 
1805              }                                                                                                     
1806              launcherInfo.hostView.setTag(launcherInfo);                                                           
1807              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1808              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1809                                                                                                                    
1810              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1811                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1812                                                                                                                    
1813              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1814          }                                                                                                         
1815          resetAddInfo();                                                                                           
1816      }                                                                                                             
1817                                                                                                                    
1818      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1819          @Override                                                                                                 
1820          public void onReceive(Context context, Intent intent) {                                                   
1821              final String action = intent.getAction();                                                             
1822              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1823                  mUserPresent = false;                                                                             
1824                  mDragLayer.clearAllResizeFrames();                                                                
1825 -                updateRunning();                                                                                  
1826 +                updateAutoAdvanceState();                                                                         
1827                                                                                                                    
1828                  // Reset AllApps to its initial state only if we are not in the middle of                         
1829                  // processing a multi-step drop                                                                   
1830 -                if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1831 +                if (mAppsView != null && mWidgetsView != null &&                                                  
1832 +                        mPendingAddInfo.container == ItemInfo.NO_ID) {                                            
1833                      showWorkspace(false);                                                                         
1834                  }                                                                                                 
1835              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1836                  mUserPresent = true;                                                                              
1837 -                updateRunning();                                                                                  
1838 +                updateAutoAdvanceState();                                                                         
1839              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1840                  mModel.resetLoadedState(false, true);                                                             
1841 -                mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1842 +                mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                                
1843                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1844              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1845                  mModel.resetLoadedState(false, true);                                                             
1846 -                mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1847 +                mModel.startLoader(PagedView.INVALID_RESTORE_PAGE,                                                
1848                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1849                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1850 -            } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1851 -                    || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1852 -                getModel().forceReload();                                                                         
1853              }                                                                                                     
1854          }                                                                                                         
1855      };                                                                                                            
1856                                                                                                                    
1857      @Override                                                                                                     
1858      public void onAttachedToWindow() {                                                                            
1859          super.onAttachedToWindow();                                                                               
1860                                                                                                                    
1861          // Listen for broadcasts related to user-presence                                                         
1862          final IntentFilter filter = new IntentFilter();                                                           
1863          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1864          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1865          // For handling managed profiles                                                                          
1866 -        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1867 -        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1868          if (ENABLE_DEBUG_INTENTS) {                                                                               
1869              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1870              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1871          }                                                                                                         
1872          registerReceiver(mReceiver, filter);                                                                      
1873          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1874          setupTransparentSystemBarsForLmp();                                                                       
1875          mAttached = true;                                                                                         
1876          mVisible = true;                                                                                          
1877      }                                                                                                             
1878                                                                                                                    
1879      /**                                                                                                           
1880       * Sets up transparent navigation and status bars in LMP.                                                     
1881       * This method is a no-op for other platform versions.                                                        
1882       */                                                                                                           
1883 -    @TargetApi(19)                                                                                                
1884 +    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
1885      private void setupTransparentSystemBarsForLmp() {                                                             
1886 -        // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1887 -        // Currently we use reflection to access the flags and the API to set the transparency                    
1888 -        // on the System bars.                                                                                    
1889          if (Utilities.isLmpOrAbove()) {                                                                           
1890 -            try {                                                                                                 
1891 -                getWindow().getAttributes().systemUiVisibility |=                                                 
1892 -                        (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1893 -                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1894 -                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1895 -                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1896 -                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1897 -                Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1898 -                        "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1899 -                getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1900 -                                                                                                                  
1901 -                Method setStatusBarColorMethod =                                                                  
1902 -                        Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1903 -                Method setNavigationBarColorMethod =                                                              
1904 -                        Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1905 -                setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1906 -                setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1907 -            } catch (NoSuchFieldException e) {                                                                    
1908 -                Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1909 -            } catch (NoSuchMethodException ex) {                                                                  
1910 -                Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1911 -            } catch (IllegalAccessException e) {                                                                  
1912 -                Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1913 -            } catch (IllegalArgumentException e) {                                                                
1914 -                Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1915 -            } catch (InvocationTargetException e) {                                                               
1916 -                Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1917 -            } finally {}                                                                                          
1918 +            Window window = getWindow();                                                                          
1919 +            window.getAttributes().systemUiVisibility |=                                                          
1920 +                    (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                            
1921 +                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                               
1922 +                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                        
1923 +            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                                  
1924 +                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                    
1925 +            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);                        
1926 +            window.setStatusBarColor(Color.TRANSPARENT);                                                          
1927 +            window.setNavigationBarColor(Color.TRANSPARENT);                                                      
1928          }                                                                                                         
1929      }                                                                                                             
1930                                                                                                                    
1931      @Override                                                                                                     
1932      public void onDetachedFromWindow() {                                                                          
1933          super.onDetachedFromWindow();                                                                             
1934          mVisible = false;                                                                                         
1935                                                                                                                    
1936          if (mAttached) {                                                                                          
1937              unregisterReceiver(mReceiver);                                                                        
1938              mAttached = false;                                                                                    
1939          }                                                                                                         
1940 -        updateRunning();                                                                                          
1941 +        updateAutoAdvanceState();                                                                                 
1942      }                                                                                                             
1943                                                                                                                    
1944      public void onWindowVisibilityChanged(int visibility) {                                                       
1945          mVisible = visibility == View.VISIBLE;                                                                    
1946 -        updateRunning();                                                                                          
1947 +        updateAutoAdvanceState();                                                                                 
1948          // The following code used to be in onResume, but it turns out onResume is called when                    
1949          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1950          // is a more appropriate event to handle                                                                  
1951          if (mVisible) {                                                                                           
1952 -            mAppsCustomizeTabHost.onWindowVisible();                                                              
1953              if (!mWorkspaceLoading) {                                                                             
1954                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1955                  // We want to let Launcher draw itself at least once before we force it to build                  
1956                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1957                  // apps is nice and speedy.                                                                       
1958                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1959                      private boolean mStarted = false;                                                             
1960                      public void onDraw() {                                                                        
1961                          if (mStarted) return;                                                                     
1962                          mStarted = true;                                                                          
1963                          // We delay the layer building a bit in order to give                                     
1964                          // other message processing a time to run.  In particular                                 
1965                          // this avoids a delay in hiding the IME if it was                                        
1966                          // currently shown, because doing that may involve                                        
1967                          // some communication back with the app.                                                  
1968                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1969                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1970                          mWorkspace.post(new Runnable() {                                                          
1971                                  public void run() {                                                               
1972                                      if (mWorkspace != null &&                                                     
1973                                              mWorkspace.getViewTreeObserver() != null) {                           
1974                                          mWorkspace.getViewTreeObserver().                                         
1975                                                  removeOnDrawListener(listener);                                   
1976                                      }                                                                             
1977                                  }                                                                                 
1978                              });                                                                                   
1979                          return;                                                                                   
1980                      }                                                                                             
1981                  });                                                                                               
1982              }                                                                                                     
1983              clearTypedText();                                                                                     
1984          }                                                                                                         
1985      }                                                                                                             
1986                                                                                                                    
1987 -    private void sendAdvanceMessage(long delay) {                                                                 
1988 +    @Thunk void sendAdvanceMessage(long delay) {                                                                  
1989          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1990          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1991          mHandler.sendMessageDelayed(msg, delay);                                                                  
1992          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1993      }                                                                                                             
1994                                                                                                                    
1995 -    private void updateRunning() {                                                                                
1996 +    @Thunk void updateAutoAdvanceState() {                                                                        
1997          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1998          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1999              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
2000              if (autoAdvanceRunning) {                                                                             
2001                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
2002                  sendAdvanceMessage(delay);                                                                        
2003              } else {                                                                                              
2004                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
2005                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
2006                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
2007                  }                                                                                                 
2008                  mHandler.removeMessages(ADVANCE_MSG);                                                             
2009                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
2010              }                                                                                                     
2011          }                                                                                                         
2012      }                                                                                                             
2013                                                                                                                    
2014      private final Handler mHandler = new Handler() {                                                              
2015          @Override                                                                                                 
2016          public void handleMessage(Message msg) {                                                                  
2017              if (msg.what == ADVANCE_MSG) {                                                                        
2018                  int i = 0;                                                                                        
2019                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
2020                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
2021                      final int delay = mAdvanceStagger * i;                                                        
2022                      if (v instanceof Advanceable) {                                                               
2023                         postDelayed(new Runnable() {                                                               
2024                             public void run() {                                                                    
2025                                 ((Advanceable) v).advance();                                                       
2026                             }                                                                                      
2027                         }, delay);                                                                                 
2028                      }                                                                                             
2029                      i++;                                                                                          
2030                  }                                                                                                 
2031                  sendAdvanceMessage(mAdvanceInterval);                                                             
2032              }                                                                                                     
2033          }                                                                                                         
2034      };                                                                                                            
2035                                                                                                                    
2036      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
2037          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
2038          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
2039          if (v instanceof Advanceable) {                                                                           
2040              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
2041              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
2042 -            updateRunning();                                                                                      
2043 +            updateAutoAdvanceState();                                                                             
2044          }                                                                                                         
2045      }                                                                                                             
2046                                                                                                                    
2047      void removeWidgetToAutoAdvance(View hostView) {                                                               
2048          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
2049              mWidgetsToAdvance.remove(hostView);                                                                   
2050 -            updateRunning();                                                                                      
2051 +            updateAutoAdvanceState();                                                                             
2052          }                                                                                                         
2053      }                                                                                                             
2054                                                                                                                    
2055      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
2056          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
2057          launcherInfo.hostView = null;                                                                             
2058      }                                                                                                             
2059                                                                                                                    
2060 -    void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
2061 +    public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                  
2062          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
2063          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
2064      }                                                                                                             
2065                                                                                                                    
2066 -    public ArrayList<AppInfo> getAllAppsList() {                                                                  
2067 -        return mAppsCustomizeContent.getApps();                                                                   
2068 -    }                                                                                                             
2069 -                                                                                                                  
2070      public DragLayer getDragLayer() {                                                                             
2071          return mDragLayer;                                                                                        
2072      }                                                                                                             
2073                                                                                                                    
2074 +    public AllAppsContainerView getAppsView() {                                                                   
2075 +        return mAppsView;                                                                                         
2076 +    }                                                                                                             
2077 +                                                                                                                  
2078 +    public WidgetsContainerView getWidgetsView() {                                                                
2079 +        return mWidgetsView;                                                                                      
2080 +    }                                                                                                             
2081 +                                                                                                                  
2082      public Workspace getWorkspace() {                                                                             
2083          return mWorkspace;                                                                                        
2084      }                                                                                                             
2085                                                                                                                    
2086      public Hotseat getHotseat() {                                                                                 
2087          return mHotseat;                                                                                          
2088      }                                                                                                             
2089                                                                                                                    
2090      public ViewGroup getOverviewPanel() {                                                                         
2091          return mOverviewPanel;                                                                                    
2092      }                                                                                                             
2093                                                                                                                    
2094      public SearchDropTargetBar getSearchBar() {                                                                   
2095          return mSearchDropTargetBar;                                                                              
2096      }                                                                                                             
2097                                                                                                                    
2098      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
2099          return mAppWidgetHost;                                                                                    
2100      }                                                                                                             
2101                                                                                                                    
2102      public LauncherModel getModel() {                                                                             
2103          return mModel;                                                                                            
2104      }                                                                                                             
2105                                                                                                                    
2106      protected SharedPreferences getSharedPrefs() {                                                                
2107          return mSharedPrefs;                                                                                      
2108 +    }                                                                                                             
2109 +                                                                                                                  
2110 +    public DeviceProfile getDeviceProfile() {                                                                     
2111 +        return mDeviceProfile;                                                                                    
2112      }                                                                                                             
2113                                                                                                                    
2114      public void closeSystemDialogs() {                                                                            
2115          getWindow().closeAllPanels();                                                                             
2116                                                                                                                    
2117          // Whatever we were doing is hereby canceled.                                                             
2118          setWaitingForResult(false);                                                                               
2119      }                                                                                                             
2120                                                                                                                    
2121      @Override                                                                                                     
2122      protected void onNewIntent(Intent intent) {                                                                   
2123          long startTime = 0;                                                                                       
2124          if (DEBUG_RESUME_TIME) {                                                                                  
2125              startTime = System.currentTimeMillis();                                                               
2126          }                                                                                                         
2127          super.onNewIntent(intent);                                                                                
2128                                                                                                                    
2129          // Close the menu                                                                                         
2130          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
2131              // also will cancel mWaitingForResult.                                                                
2132              closeSystemDialogs();                                                                                 
2133                                                                                                                    
2134              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
2135                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
2136                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
2137                                                                                                                    
2138              if (mWorkspace == null) {                                                                             
2139                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
2140                  return;                                                                                           
2141              }                                                                                                     
2142              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2143              // In all these cases, only animate if we're already on home                                          
2144              mWorkspace.exitWidgetResizeMode();                                                                    
2145                                                                                                                    
2146              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
2147                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
2148              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
2149                      openFolder == null && moveToDefaultScreen) {                                                  
2150                  mWorkspace.moveToDefaultScreen(true);                                                             
2151              }                                                                                                     
2152                                                                                                                    
2153              closeFolder();                                                                                        
2154              exitSpringLoadedDragMode();                                                                           
2155                                                                                                                    
2156              // If we are already on home, then just animate back to the workspace,                                
2157              // otherwise, just wait until onResume to set the state back to Workspace                             
2158              if (alreadyOnHome) {                                                                                  
2159                  showWorkspace(true);                                                                              
2160              } else {                                                                                              
2161                  mOnResumeState = State.WORKSPACE;                                                                 
2162              }                                                                                                     
2163                                                                                                                    
2164              final View v = getWindow().peekDecorView();                                                           
2165              if (v != null && v.getWindowToken() != null) {                                                        
2166                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
2167                          INPUT_METHOD_SERVICE);                                                                    
2168                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
2169              }                                                                                                     
2170                                                                                                                    
2171 -            // Reset the apps customize page                                                                      
2172 -            if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
2173 -                mAppsCustomizeTabHost.reset();                                                                    
2174 +            // Reset the apps view                                                                                
2175 +            if (!alreadyOnHome && mAppsView != null) {                                                            
2176 +                mAppsView.scrollToTop();                                                                          
2177 +            }                                                                                                     
2178 +                                                                                                                  
2179 +            // Reset the widgets view                                                                             
2180 +            if (!alreadyOnHome && mWidgetsView != null) {                                                         
2181 +                mWidgetsView.scrollToTop();                                                                       
2182              }                                                                                                     
2183                                                                                                                    
2184              if (mLauncherCallbacks != null) {                                                                     
2185                  mLauncherCallbacks.onHomeIntent();                                                                
2186              }                                                                                                     
2187          }                                                                                                         
2188                                                                                                                    
2189          if (DEBUG_RESUME_TIME) {                                                                                  
2190              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
2191          }                                                                                                         
2192                                                                                                                    
2193          if (mLauncherCallbacks != null) {                                                                         
2194              mLauncherCallbacks.onNewIntent(intent);                                                               
2195          }                                                                                                         
2196      }                                                                                                             
2197                                                                                                                    
2198      @Override                                                                                                     
2199      public void onRestoreInstanceState(Bundle state) {                                                            
2200          super.onRestoreInstanceState(state);                                                                      
2201          for (int page: mSynchronouslyBoundPages) {                                                                
2202              mWorkspace.restoreInstanceStateForChild(page);                                                        
2203          }                                                                                                         
2204      }                                                                                                             
2205                                                                                                                    
2206      @Override                                                                                                     
2207      protected void onSaveInstanceState(Bundle outState) {                                                         
2208          if (mWorkspace.getChildCount() > 0) {                                                                     
2209              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
2210                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
2211          }                                                                                                         
2212          super.onSaveInstanceState(outState);                                                                      
2213                                                                                                                    
2214          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
2215          // We close any open folder since it will not be re-opened, and we need to make sure                      
2216          // this state is reflected.                                                                               
2217          closeFolder();                                                                                            
2218                                                                                                                    
2219          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
2220                  mWaitingForResult) {                                                                              
2221              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
2222              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
2223              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
2224              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
2225              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2226              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2227              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2228              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2229          }                                                                                                         
2230                                                                                                                    
2231 -        if (mFolderInfo != null && mWaitingForResult) {                                                           
2232 -            outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2233 -            outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2234 -        }                                                                                                         
2235 -                                                                                                                  
2236 -        // Save the current AppsCustomize tab                                                                     
2237 -        if (mAppsCustomizeTabHost != null) {                                                                      
2238 -            AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2239 -            String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2240 -            if (currentTabTag != null) {                                                                          
2241 -                outState.putString("apps_customize_currentTab", currentTabTag);                                   
2242 -            }                                                                                                     
2243 -            int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2244 -            outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2245 -        }                                                                                                         
2246 +        // Save the current widgets tray?                                                                         
2247 +        // TODO(hyunyoungs)                                                                                       
2248          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2249                                                                                                                    
2250          if (mLauncherCallbacks != null) {                                                                         
2251              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2252          }                                                                                                         
2253      }                                                                                                             
2254                                                                                                                    
2255      @Override                                                                                                     
2256      public void onDestroy() {                                                                                     
2257          super.onDestroy();                                                                                        
2258                                                                                                                    
2259          // Remove all pending runnables                                                                           
2260          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2261          mHandler.removeMessages(0);                                                                               
2262          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2263                                                                                                                    
2264          // Stop callbacks from LauncherModel                                                                      
2265          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2266                                                                                                                    
2267          // It's possible to receive onDestroy after a new Launcher activity has                                   
2268          // been created. In this case, don't interfere with the new Launcher.                                     
2269          if (mModel.isCurrentCallbacks(this)) {                                                                    
2270              mModel.stopLoader();                                                                                  
2271              app.setLauncher(null);                                                                                
2272          }                                                                                                         
2273                                                                                                                    
2274          try {                                                                                                     
2275              mAppWidgetHost.stopListening();                                                                       
2276          } catch (NullPointerException ex) {                                                                       
2277              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2278          }                                                                                                         
2279          mAppWidgetHost = null;                                                                                    
2280                                                                                                                    
2281          mWidgetsToAdvance.clear();                                                                                
2282                                                                                                                    
2283          TextKeyListener.getInstance().release();                                                                  
2284 -                                                                                                                  
2285 -        // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2286 -        // to prevent leaking Launcher activities on orientation change.                                          
2287 -        if (mModel != null) {                                                                                     
2288 -            mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2289 -        }                                                                                                         
2290                                                                                                                    
2291          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2292          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2293                                                                                                                    
2294          mDragLayer.clearAllResizeFrames();                                                                        
2295          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2296          mWorkspace.removeAllWorkspaceScreens();                                                                   
2297          mWorkspace = null;                                                                                        
2298          mDragController = null;                                                                                   
2299                                                                                                                    
2300          LauncherAnimUtils.onDestroyActivity();                                                                    
2301                                                                                                                    
2302          if (mLauncherCallbacks != null) {                                                                         
2303              mLauncherCallbacks.onDestroy();                                                                       
2304          }                                                                                                         
2305      }                                                                                                             
2306                                                                                                                    
2307      public DragController getDragController() {                                                                   
2308          return mDragController;                                                                                   
2309      }                                                                                                             
2310                                                                                                                    
2311      @Override                                                                                                     
2312      public void startActivityForResult(Intent intent, int requestCode) {                                          
2313          onStartForResult(requestCode);                                                                            
2314          super.startActivityForResult(intent, requestCode);                                                        
2315      }                                                                                                             
2316                                                                                                                    
2317      @Override                                                                                                     
2318      public void startIntentSenderForResult (IntentSender intent, int requestCode,                                 
2319              Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {                
2320          onStartForResult(requestCode);                                                                            
2321          try {                                                                                                     
2322              super.startIntentSenderForResult(intent, requestCode,                                                 
2323                  fillInIntent, flagsMask, flagsValues, extraFlags, options);                                       
2324          } catch (IntentSender.SendIntentException e) {                                                            
2325              throw new ActivityNotFoundException();                                                                
2326          }                                                                                                         
2327      }                                                                                                             
2328                                                                                                                    
2329      private void onStartForResult(int requestCode) {                                                              
2330          if (requestCode >= 0) {                                                                                   
2331              setWaitingForResult(true);                                                                            
2332          }                                                                                                         
2333      }                                                                                                             
2334                                                                                                                    
2335      /**                                                                                                           
2336       * Indicates that we want global search for this activity by setting the globalSearch                         
2337       * argument for {@link #startSearch} to true.                                                                 
2338       */                                                                                                           
2339      @Override                                                                                                     
2340      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2341              Bundle appSearchData, boolean globalSearch) {                                                         
2342                                                                                                                    
2343 -        showWorkspace(true);                                                                                      
2344 -                                                                                                                  
2345          if (initialQuery == null) {                                                                               
2346              // Use any text typed in the launcher as the initial query                                            
2347              initialQuery = getTypedText();                                                                        
2348          }                                                                                                         
2349          if (appSearchData == null) {                                                                              
2350              appSearchData = new Bundle();                                                                         
2351              appSearchData.putString("source", "launcher-search");                                                 
2352          }                                                                                                         
2353          Rect sourceBounds = new Rect();                                                                           
2354          if (mSearchDropTargetBar != null) {                                                                       
2355              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2356          }                                                                                                         
2357                                                                                                                    
2358          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2359                  appSearchData, sourceBounds);                                                                     
2360          if (clearTextImmediately) {                                                                               
2361              clearTypedText();                                                                                     
2362          }                                                                                                         
2363 +                                                                                                                  
2364 +        // We need to show the workspace after starting the search                                                
2365 +        showWorkspace(true);                                                                                      
2366      }                                                                                                             
2367                                                                                                                    
2368      /**                                                                                                           
2369       * Start a text search.                                                                                       
2370       *                                                                                                            
2371       * @return {@code true} if the search will start immediately, so any further keypresses                       
2372       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2373       * to buffer keypresses.                                                                                      
2374       */                                                                                                           
2375      public boolean startSearch(String initialQuery,                                                               
2376              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2377          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2378              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2379                      sourceBounds);                                                                                
2380          }                                                                                                         
2381                                                                                                                    
2382          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2383                  appSearchData, sourceBounds);                                                                     
2384          return false;                                                                                             
2385      }                                                                                                             
2386                                                                                                                    
2387      /**                                                                                                           
2388       * Starts the global search activity. This code is a copied from SearchManager                                
2389       */                                                                                                           
2390      private void startGlobalSearch(String initialQuery,                                                           
2391              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2392          final SearchManager searchManager =                                                                       
2393              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2394          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2395          if (globalSearchActivity == null) {                                                                       
2396              Log.w(TAG, "No global search activity found.");                                                       
2397              return;                                                                                               
2398          }                                                                                                         
2399          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2400          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2401          intent.setComponent(globalSearchActivity);                                                                
2402          // Make sure that we have a Bundle to put source in                                                       
2403          if (appSearchData == null) {                                                                              
2404              appSearchData = new Bundle();                                                                         
2405          } else {                                                                                                  
2406              appSearchData = new Bundle(appSearchData);                                                            
2407          }                                                                                                         
2408          // Set source to package name of app that starts global search if not set already.                        
2409          if (!appSearchData.containsKey("source")) {                                                               
2410              appSearchData.putString("source", getPackageName());                                                  
2411          }                                                                                                         
2412          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2413          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2414              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2415          }                                                                                                         
2416          if (selectInitialQuery) {                                                                                 
2417              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2418          }                                                                                                         
2419          intent.setSourceBounds(sourceBounds);                                                                     
2420          try {                                                                                                     
2421              startActivity(intent);                                                                                
2422          } catch (ActivityNotFoundException ex) {                                                                  
2423              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2424          }                                                                                                         
2425      }                                                                                                             
2426                                                                                                                    
2427      public boolean isOnCustomContent() {                                                                          
2428          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2429      }                                                                                                             
2430                                                                                                                    
2431      @Override                                                                                                     
2432      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2433          super.onPrepareOptionsMenu(menu);                                                                         
2434          if (!isOnCustomContent()) {                                                                               
2435              // Close any open folders                                                                             
2436              closeFolder();                                                                                        
2437              // Stop resizing any widgets                                                                          
2438              mWorkspace.exitWidgetResizeMode();                                                                    
2439              if (!mWorkspace.isInOverviewMode()) {                                                                 
2440                  // Show the overview mode                                                                         
2441                  showOverviewMode(true);                                                                           
2442              } else {                                                                                              
2443                  showWorkspace(true);                                                                              
2444              }                                                                                                     
2445          }                                                                                                         
2446          if (mLauncherCallbacks != null) {                                                                         
2447              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2448          }                                                                                                         
2449                                                                                                                    
2450          return false;                                                                                             
2451      }                                                                                                             
2452                                                                                                                    
2453      @Override                                                                                                     
2454      public boolean onSearchRequested() {                                                                          
2455          startSearch(null, false, null, true);                                                                     
2456          // Use a custom animation for launching search                                                            
2457          return true;                                                                                              
2458      }                                                                                                             
2459                                                                                                                    
2460      public boolean isWorkspaceLocked() {                                                                          
2461          return mWorkspaceLoading || mWaitingForResult;                                                            
2462      }                                                                                                             
2463                                                                                                                    
2464      public boolean isWorkspaceLoading() {                                                                         
2465          return mWorkspaceLoading;                                                                                 
2466      }                                                                                                             
2467                                                                                                                    
2468      private void setWorkspaceLoading(boolean value) {                                                             
2469          boolean isLocked = isWorkspaceLocked();                                                                   
2470          mWorkspaceLoading = value;                                                                                
2471          if (isLocked != isWorkspaceLocked()) {                                                                    
2472              onWorkspaceLockedChanged();                                                                           
2473          }                                                                                                         
2474      }                                                                                                             
2475                                                                                                                    
2476      private void setWaitingForResult(boolean value) {                                                             
2477          boolean isLocked = isWorkspaceLocked();                                                                   
2478          mWaitingForResult = value;                                                                                
2479          if (isLocked != isWorkspaceLocked()) {                                                                    
2480              onWorkspaceLockedChanged();                                                                           
2481          }                                                                                                         
2482      }                                                                                                             
2483                                                                                                                    
2484      protected void onWorkspaceLockedChanged() {                                                                   
2485          if (mLauncherCallbacks != null) {                                                                         
2486              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2487          }                                                                                                         
2488      }                                                                                                             
2489                                                                                                                    
2490      private void resetAddInfo() {                                                                                 
2491          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2492          mPendingAddInfo.screenId = -1;                                                                            
2493          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2494          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2495          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2496          mPendingAddInfo.dropPos = null;                                                                           
2497      }                                                                                                             
2498                                                                                                                    
2499      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2500              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2501          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2502      }                                                                                                             
2503                                                                                                                    
2504      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2505              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2506              int delay) {                                                                                          
2507          if (appWidgetInfo.configure != null) {                                                                    
2508              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2509              mPendingAddWidgetId = appWidgetId;                                                                    
2510                                                                                                                    
2511              // Launch over to configure widget, if needed                                                         
2512              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2513                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2514                                                                                                                    
2515          } else {                                                                                                  
2516              // Otherwise just add it                                                                              
2517              Runnable onComplete = new Runnable() {                                                                
2518                  @Override                                                                                         
2519                  public void run() {                                                                               
2520                      // Exit spring loaded mode if necessary after adding the widget                               
2521                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2522                              null);                                                                                
2523                  }                                                                                                 
2524              };                                                                                                    
2525              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2526                      appWidgetInfo);                                                                               
2527              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2528          }                                                                                                         
2529      }                                                                                                             
2530                                                                                                                    
2531      protected void moveToCustomContentScreen(boolean animate) {                                                   
2532          // Close any folders that may be open.                                                                    
2533          closeFolder();                                                                                            
2534          mWorkspace.moveToCustomContentScreen(animate);                                                            
2535      }                                                                                                             
2536                                                                                                                    
2537      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2538              int[] cell, int spanX, int spanY) {                                                                   
2539          switch (info.itemType) {                                                                                  
2540              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2541              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2542                  int span[] = new int[2];                                                                          
2543                  span[0] = spanX;                                                                                  
2544                  span[1] = spanY;                                                                                  
2545                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2546                          container, screenId, cell, span);                                                         
2547                  break;                                                                                            
2548              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2549                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2550                  break;                                                                                            
2551              default:                                                                                              
2552                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2553              }                                                                                                     
2554      }                                                                                                             
2555                                                                                                                    
2556      /**                                                                                                           
2557       * Process a shortcut drop.                                                                                   
2558       *                                                                                                            
2559       * @param componentName The name of the component                                                             
2560       * @param screenId The ID of the screen where it should be added                                              
2561       * @param cell The cell it should be added to, optional                                                       
2562       */                                                                                                           
2563      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2564              int[] cell) {                                                                                         
2565          resetAddInfo();                                                                                           
2566          mPendingAddInfo.container = container;                                                                    
2567          mPendingAddInfo.screenId = screenId;                                                                      
2568          mPendingAddInfo.dropPos = null;                                                                           
2569                                                                                                                    
2570          if (cell != null) {                                                                                       
2571              mPendingAddInfo.cellX = cell[0];                                                                      
2572              mPendingAddInfo.cellY = cell[1];                                                                      
2573          }                                                                                                         
2574                                                                                                                    
2575          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2576          createShortcutIntent.setComponent(componentName);                                                         
2577          processShortcut(createShortcutIntent);                                                                    
2578      }                                                                                                             
2579                                                                                                                    
2580      /**                                                                                                           
2581       * Process a widget drop.                                                                                     
2582       *                                                                                                            
2583       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2584       * @param screenId The ID of the screen where it should be added                                              
2585       * @param cell The cell it should be added to, optional                                                       
2586       */                                                                                                           
2587      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2588              int[] cell, int[] span) {                                                                             
2589          resetAddInfo();                                                                                           
2590          mPendingAddInfo.container = info.container = container;                                                   
2591          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2592          mPendingAddInfo.dropPos = null;                                                                           
2593          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2594          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2595                                                                                                                    
2596          if (cell != null) {                                                                                       
2597              mPendingAddInfo.cellX = cell[0];                                                                      
2598              mPendingAddInfo.cellY = cell[1];                                                                      
2599          }                                                                                                         
2600          if (span != null) {                                                                                       
2601              mPendingAddInfo.spanX = span[0];                                                                      
2602              mPendingAddInfo.spanY = span[1];                                                                      
2603          }                                                                                                         
2604                                                                                                                    
2605          AppWidgetHostView hostView = info.boundWidget;                                                            
2606          int appWidgetId;                                                                                          
2607          if (hostView != null) {                                                                                   
2608              appWidgetId = hostView.getAppWidgetId();                                                              
2609              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2610          } else {                                                                                                  
2611              // In this case, we either need to start an activity to get permission to bind                        
2612              // the widget, or we need to start an activity to configure the widget, or both.                      
2613              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2614              Bundle options = info.bindOptions;                                                                    
2615                                                                                                                    
2616              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2617                      appWidgetId, info.info, options);                                                             
2618              if (success) {                                                                                        
2619                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2620              } else {                                                                                              
2621                  mPendingAddWidgetInfo = info.info;                                                                
2622                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2623                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2624                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2625                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2626                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2627                  // TODO: we need to make sure that this accounts for the options bundle.                          
2628                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2629                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2630              }                                                                                                     
2631          }                                                                                                         
2632      }                                                                                                             
2633                                                                                                                    
2634      void processShortcut(Intent intent) {                                                                         
2635          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2636      }                                                                                                             
2637                                                                                                                    
2638      void processWallpaper(Intent intent) {                                                                        
2639          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2640      }                                                                                                             
2641                                                                                                                    
2642      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2643              int cellY) {                                                                                          
2644          final FolderInfo folderInfo = new FolderInfo();                                                           
2645          folderInfo.title = getText(R.string.folder_name);                                                         
2646                                                                                                                    
2647          // Update the model                                                                                       
2648 -        LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2649 -                false);                                                                                           
2650 +        LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                           
2651 +                cellX, cellY);                                                                                    
2652          sFolders.put(folderInfo.id, folderInfo);                                                                  
2653                                                                                                                    
2654          // Create the view                                                                                        
2655          FolderIcon newFolder =                                                                                    
2656              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2657          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2658                  isWorkspaceLocked());                                                                             
2659          // Force measure the new folder icon                                                                      
2660          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2661          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2662          return newFolder;                                                                                         
2663      }                                                                                                             
2664                                                                                                                    
2665      void removeFolder(FolderInfo folder) {                                                                        
2666          sFolders.remove(folder.id);                                                                               
2667 -    }                                                                                                             
2668 -                                                                                                                  
2669 -    protected ComponentName getWallpaperPickerComponent() {                                                       
2670 -        if (mLauncherCallbacks != null) {                                                                         
2671 -            return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2672 -        }                                                                                                         
2673 -        return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2674      }                                                                                                             
2675                                                                                                                    
2676      /**                                                                                                           
2677       * Registers various content observers. The current implementation registers                                  
2678       * only a favorites observer to keep track of the favorites applications.                                     
2679       */                                                                                                           
2680      private void registerContentObservers() {                                                                     
2681          ContentResolver resolver = getContentResolver();                                                          
2682          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2683                  true, mWidgetObserver);                                                                           
2684      }                                                                                                             
2685                                                                                                                    
2686      @Override                                                                                                     
2687      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2688          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2689              switch (event.getKeyCode()) {                                                                         
2690                  case KeyEvent.KEYCODE_HOME:                                                                       
2691                      return true;                                                                                  
2692                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2693                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2694                          dumpState();                                                                              
2695                          return true;                                                                              
2696                      }                                                                                             
2697                      break;                                                                                        
2698              }                                                                                                     
2699          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2700              switch (event.getKeyCode()) {                                                                         
2701                  case KeyEvent.KEYCODE_HOME:                                                                       
2702                      return true;                                                                                  
2703              }                                                                                                     
2704          }                                                                                                         
2705                                                                                                                    
2706          return super.dispatchKeyEvent(event);                                                                     
2707      }                                                                                                             
2708                                                                                                                    
2709      @Override                                                                                                     
2710      public void onBackPressed() {                                                                                 
2711          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2712              return;                                                                                               
2713          }                                                                                                         
2714                                                                                                                    
2715 -        if (isAllAppsVisible()) {                                                                                 
2716 -            if (mAppsCustomizeContent.getContentType() ==                                                         
2717 -                    AppsCustomizePagedView.ContentType.Applications) {                                            
2718 -                showWorkspace(true);                                                                              
2719 -            } else {                                                                                              
2720 -                showOverviewMode(true);                                                                           
2721 -            }                                                                                                     
2722 +        LauncherAccessibilityDelegate delegate =                                                                  
2723 +                LauncherAppState.getInstance().getAccessibilityDelegate();                                        
2724 +        if (delegate != null && delegate.onBackPressed()) {                                                       
2725 +            return;                                                                                               
2726 +        }                                                                                                         
2727 +                                                                                                                  
2728 +        if (isAppsViewVisible()) {                                                                                
2729 +            showWorkspace(true);                                                                                  
2730 +        } else if (isWidgetsViewVisible())  {                                                                     
2731 +            showOverviewMode(true);                                                                               
2732          } else if (mWorkspace.isInOverviewMode()) {                                                               
2733 -            mWorkspace.exitOverviewMode(true);                                                                    
2734 +            showWorkspace(true);                                                                                  
2735          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2736              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2737              if (openFolder.isEditingName()) {                                                                     
2738                  openFolder.dismissEditingName();                                                                  
2739              } else {                                                                                              
2740                  closeFolder();                                                                                    
2741              }                                                                                                     
2742          } else {                                                                                                  
2743              mWorkspace.exitWidgetResizeMode();                                                                    
2744                                                                                                                    
2745              // Back button is a no-op here, but give at least some feedback for the button press                  
2746              mWorkspace.showOutlinesTemporarily();                                                                 
2747          }                                                                                                         
2748      }                                                                                                             
2749                                                                                                                    
2750      /**                                                                                                           
2751       * Re-listen when widgets are reset.                                                                          
2752       */                                                                                                           
2753 -    private void onAppWidgetReset() {                                                                             
2754 +    @Thunk void onAppWidgetReset() {                                                                              
2755          if (mAppWidgetHost != null) {                                                                             
2756              mAppWidgetHost.startListening();                                                                      
2757          }                                                                                                         
2758      }                                                                                                             
2759                                                                                                                    
2760      /**                                                                                                           
2761       * Launches the intent referred by the clicked shortcut.                                                      
2762       *                                                                                                            
2763       * @param v The view representing the clicked shortcut.                                                       
2764       */                                                                                                           
2765      public void onClick(View v) {                                                                                 
2766          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2767          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2768          if (v.getWindowToken() == null) {                                                                         
2769              return;                                                                                               
2770          }                                                                                                         
2771                                                                                                                    
2772          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2773              return;                                                                                               
2774          }                                                                                                         
2775                                                                                                                    
2776          if (v instanceof Workspace) {                                                                             
2777              if (mWorkspace.isInOverviewMode()) {                                                                  
2778 -                mWorkspace.exitOverviewMode(true);                                                                
2779 +                showWorkspace(true);                                                                              
2780              }                                                                                                     
2781              return;                                                                                               
2782          }                                                                                                         
2783                                                                                                                    
2784          if (v instanceof CellLayout) {                                                                            
2785              if (mWorkspace.isInOverviewMode()) {                                                                  
2786 -                mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2787 +                showWorkspace(mWorkspace.indexOfChild(v), true);                                                  
2788              }                                                                                                     
2789          }                                                                                                         
2790                                                                                                                    
2791          Object tag = v.getTag();                                                                                  
2792          if (tag instanceof ShortcutInfo) {                                                                        
2793              onClickAppShortcut(v);                                                                                
2794          } else if (tag instanceof FolderInfo) {                                                                   
2795              if (v instanceof FolderIcon) {                                                                        
2796                  onClickFolderIcon(v);                                                                             
2797              }                                                                                                     
2798          } else if (v == mAllAppsButton) {                                                                         
2799              onClickAllAppsButton(v);                                                                              
2800          } else if (tag instanceof AppInfo) {                                                                      
2801              startAppShortcutOrInfoActivity(v);                                                                    
2802          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2803              if (v instanceof PendingAppWidgetHostView) {                                                          
2804                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2805              }                                                                                                     
2806          }                                                                                                         
2807      }                                                                                                             
2808                                                                                                                    
2809      public void onClickPagedViewIcon(View v) {                                                                    
2810          startAppShortcutOrInfoActivity(v);                                                                        
2811          if (mLauncherCallbacks != null) {                                                                         
2812              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2813          }                                                                                                         
2814      }                                                                                                             
2815                                                                                                                    
2816 +    @SuppressLint("ClickableViewAccessibility")                                                                   
2817      public boolean onTouch(View v, MotionEvent event) {                                                           
2818          return false;                                                                                             
2819      }                                                                                                             
2820                                                                                                                    
2821      /**                                                                                                           
2822       * Event handler for the app widget view which has not fully restored.                                        
2823       */                                                                                                           
2824      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2825          if (mIsSafeModeEnabled) {                                                                                 
2826              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2827              return;                                                                                               
2828          }                                                                                                         
2829                                                                                                                    
2830          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2831          if (v.isReadyForClickSetup()) {                                                                           
2832              int widgetId = info.appWidgetId;                                                                      
2833              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2834              if (appWidgetInfo != null) {                                                                          
2835                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2836                          this, appWidgetInfo);                                                                     
2837                  mPendingAddInfo.copyFrom(info);                                                                   
2838                  mPendingAddWidgetId = widgetId;                                                                   
2839                                                                                                                    
2840                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2841                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2842              }                                                                                                     
2843          } else if (info.installProgress < 0) {                                                                    
2844              // The install has not been queued                                                                    
2845              final String packageName = info.providerName.getPackageName();                                        
2846              showBrokenAppInstallDialog(packageName,                                                               
2847                  new DialogInterface.OnClickListener() {                                                           
2848                      public void onClick(DialogInterface dialog, int id) {                                         
2849                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2850                      }                                                                                             
2851                  });                                                                                               
2852          } else {                                                                                                  
2853              // Download has started.                                                                              
2854              final String packageName = info.providerName.getPackageName();                                        
2855              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2856          }                                                                                                         
2857      }                                                                                                             
2858                                                                                                                    
2859      /**                                                                                                           
2860       * Event handler for the "grid" button that appears on the home screen, which                                 
2861       * enters all apps mode.                                                                                      
2862       *                                                                                                            
2863       * @param v The view that was clicked.                                                                        
2864       */                                                                                                           
2865      protected void onClickAllAppsButton(View v) {                                                                 
2866          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2867 -        if (isAllAppsVisible()) {                                                                                 
2868 +        if (isAppsViewVisible()) {                                                                                
2869              showWorkspace(true);                                                                                  
2870          } else {                                                                                                  
2871 -            showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2872 -        }                                                                                                         
2873 -        if (mLauncherCallbacks != null) {                                                                         
2874 -            mLauncherCallbacks.onClickAllAppsButton(v);                                                           
2875 +            // Try and refresh the set of predicted apps before we enter launcher                                 
2876 +            showAppsView(true /* animated */, false /* resetListToTop */,                                         
2877 +                    true /* updatePredictedApps */);                                                              
2878          }                                                                                                         
2879      }                                                                                                             
2880                                                                                                                    
2881      private void showBrokenAppInstallDialog(final String packageName,                                             
2882              DialogInterface.OnClickListener onSearchClickListener) {                                              
2883          new AlertDialog.Builder(this)                                                                             
2884              .setTitle(R.string.abandoned_promises_title)                                                          
2885              .setMessage(R.string.abandoned_promise_explanation)                                                   
2886              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2887              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2888                  new DialogInterface.OnClickListener() {                                                           
2889                      public void onClick(DialogInterface dialog, int id) {                                         
2890                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2891                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2892                      }                                                                                             
2893                  })                                                                                                
2894              .create().show();                                                                                     
2895          return;                                                                                                   
2896      }                                                                                                             
2897                                                                                                                    
2898      /**                                                                                                           
2899       * Event handler for an app shortcut click.                                                                   
2900       *                                                                                                            
2901       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2902       */                                                                                                           
2903      protected void onClickAppShortcut(final View v) {                                                             
2904          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2905          Object tag = v.getTag();                                                                                  
2906          if (!(tag instanceof ShortcutInfo)) {                                                                     
2907              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2908          }                                                                                                         
2909                                                                                                                    
2910          // Open shortcut                                                                                          
2911          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2912                                                                                                                    
2913          if (shortcut.isDisabled != 0) {                                                                           
2914              int error = R.string.activity_not_available;                                                          
2915              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2916                  error = R.string.safemode_shortcut_error;                                                         
2917              }                                                                                                     
2918              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2919              return;                                                                                               
2920          }                                                                                                         
2921                                                                                                                    
2922          final Intent intent = shortcut.intent;                                                                    
2923                                                                                                                    
2924          // Check for special shortcuts                                                                            
2925          if (intent.getComponent() != null) {                                                                      
2926              final String shortcutClass = intent.getComponent().getClassName();                                    
2927                                                                                                                    
2928              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2929                  MemoryDumpActivity.startDump(this);                                                               
2930                  return;                                                                                           
2931              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2932                  toggleShowWeightWatcher();                                                                        
2933                  return;                                                                                           
2934              }                                                                                                     
2935          }                                                                                                         
2936                                                                                                                    
2937          // Check for abandoned promise                                                                            
2938          if ((v instanceof BubbleTextView)                                                                         
2939                  && shortcut.isPromise()                                                                           
2940                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2941              showBrokenAppInstallDialog(                                                                           
2942                      shortcut.getTargetComponent().getPackageName(),                                               
2943                      new DialogInterface.OnClickListener() {                                                       
2944                          public void onClick(DialogInterface dialog, int id) {                                     
2945                              startAppShortcutOrInfoActivity(v);                                                    
2946                          }                                                                                         
2947                      });                                                                                           
2948              return;                                                                                               
2949          }                                                                                                         
2950                                                                                                                    
2951          // Start activities                                                                                       
2952          startAppShortcutOrInfoActivity(v);                                                                        
2953                                                                                                                    
2954          if (mLauncherCallbacks != null) {                                                                         
2955              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2956          }                                                                                                         
2957      }                                                                                                             
2958                                                                                                                    
2959 -    private void startAppShortcutOrInfoActivity(View v) {                                                         
2960 +    @Thunk void startAppShortcutOrInfoActivity(View v) {                                                          
2961          Object tag = v.getTag();                                                                                  
2962          final ShortcutInfo shortcut;                                                                              
2963          final Intent intent;                                                                                      
2964          if (tag instanceof ShortcutInfo) {                                                                        
2965              shortcut = (ShortcutInfo) tag;                                                                        
2966              intent = shortcut.intent;                                                                             
2967              int[] pos = new int[2];                                                                               
2968              v.getLocationOnScreen(pos);                                                                           
2969              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2970                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2971                                                                                                                    
2972          } else if (tag instanceof AppInfo) {                                                                      
2973              shortcut = null;                                                                                      
2974              intent = ((AppInfo) tag).intent;                                                                      
2975          } else {                                                                                                  
2976              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2977          }                                                                                                         
2978                                                                                                                    
2979          boolean success = startActivitySafely(v, intent, tag);                                                    
2980          mStats.recordLaunch(intent, shortcut);                                                                    
2981                                                                                                                    
2982          if (success && v instanceof BubbleTextView) {                                                             
2983              mWaitingForResume = (BubbleTextView) v;                                                               
2984              mWaitingForResume.setStayPressed(true);                                                               
2985          }                                                                                                         
2986      }                                                                                                             
2987                                                                                                                    
2988      /**                                                                                                           
2989       * Event handler for a folder icon click.                                                                     
2990       *                                                                                                            
2991       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2992       */                                                                                                           
2993      protected void onClickFolderIcon(View v) {                                                                    
2994          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2995          if (!(v instanceof FolderIcon)){                                                                          
2996              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2997          }                                                                                                         
2998                                                                                                                    
2999          FolderIcon folderIcon = (FolderIcon) v;                                                                   
3000          final FolderInfo info = folderIcon.getFolderInfo();                                                       
3001          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
3002                                                                                                                    
3003          // If the folder info reports that the associated folder is open, then verify that                        
3004          // it is actually opened. There have been a few instances where this gets out of sync.                    
3005          if (info.opened && openFolder == null) {                                                                  
3006              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
3007                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
3008              info.opened = false;                                                                                  
3009          }                                                                                                         
3010                                                                                                                    
3011          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
3012              // Close any open folder                                                                              
3013              closeFolder();                                                                                        
3014              // Open the requested folder                                                                          
3015              openFolder(folderIcon);                                                                               
3016          } else {                                                                                                  
3017              // Find the open folder...                                                                            
3018              int folderScreen;                                                                                     
3019              if (openFolder != null) {                                                                             
3020                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
3021                  // .. and close it                                                                                
3022                  closeFolder(openFolder);                                                                          
3023                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
3024                      // Close any folder open on the current screen                                                
3025                      closeFolder();                                                                                
3026                      // Pull the folder onto this screen                                                           
3027                      openFolder(folderIcon);                                                                       
3028                  }                                                                                                 
3029              }                                                                                                     
3030          }                                                                                                         
3031                                                                                                                    
3032          if (mLauncherCallbacks != null) {                                                                         
3033              mLauncherCallbacks.onClickFolderIcon(v);                                                              
3034          }                                                                                                         
3035      }                                                                                                             
3036                                                                                                                    
3037      /**                                                                                                           
3038       * Event handler for the (Add) Widgets button that appears after a long press                                 
3039       * on the home screen.                                                                                        
3040       */                                                                                                           
3041      protected void onClickAddWidgetButton(View view) {                                                            
3042          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
3043          if (mIsSafeModeEnabled) {                                                                                 
3044              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
3045          } else {                                                                                                  
3046 -            showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  
3047 +            showWidgetsView(true /* animated */, true /* resetPageToZero */);                                     
3048              if (mLauncherCallbacks != null) {                                                                     
3049                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
3050              }                                                                                                     
3051          }                                                                                                         
3052      }                                                                                                             
3053                                                                                                                    
3054      /**                                                                                                           
3055       * Event handler for the wallpaper picker button that appears after a long press                              
3056       * on the home screen.                                                                                        
3057       */                                                                                                           
3058      protected void onClickWallpaperPicker(View v) {                                                               
3059          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
3060 -        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
3061 -        pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
3062 -        startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
3063 +        startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),              
3064 +                REQUEST_PICK_WALLPAPER);                                                                          
3065                                                                                                                    
3066          if (mLauncherCallbacks != null) {                                                                         
3067              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
3068          }                                                                                                         
3069      }                                                                                                             
3070                                                                                                                    
3071      /**                                                                                                           
3072       * Event handler for a click on the settings button that appears after a long press                           
3073       * on the home screen.                                                                                        
3074       */                                                                                                           
3075      protected void onClickSettingsButton(View v) {                                                                
3076          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
3077          if (mLauncherCallbacks != null) {                                                                         
3078              mLauncherCallbacks.onClickSettingsButton(v);                                                          
3079          }                                                                                                         
3080      }                                                                                                             
3081                                                                                                                    
3082      public void onTouchDownAllAppsButton(View v) {                                                                
3083          // Provide the same haptic feedback that the system offers for virtual keys.                              
3084          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
3085      }                                                                                                             
3086                                                                                                                    
3087      public void performHapticFeedbackOnTouchDown(View v) {                                                        
3088          // Provide the same haptic feedback that the system offers for virtual keys.                              
3089          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
3090      }                                                                                                             
3091                                                                                                                    
3092      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
3093          if (mHapticFeedbackTouchListener == null) {                                                               
3094              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
3095 +                @SuppressLint("ClickableViewAccessibility")                                                       
3096                  @Override                                                                                         
3097                  public boolean onTouch(View v, MotionEvent event) {                                               
3098                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
3099                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
3100                      }                                                                                             
3101                      return false;                                                                                 
3102                  }                                                                                                 
3103              };                                                                                                    
3104          }                                                                                                         
3105          return mHapticFeedbackTouchListener;                                                                      
3106      }                                                                                                             
3107                                                                                                                    
3108      public void onDragStarted(View view) {                                                                        
3109          if (isOnCustomContent()) {                                                                                
3110              // Custom content screen doesn't participate in drag and drop. If on custom                           
3111              // content screen, move to default.                                                                   
3112              moveWorkspaceToDefaultScreen();                                                                       
3113          }                                                                                                         
3114                                                                                                                    
3115          if (mLauncherCallbacks != null) {                                                                         
3116              mLauncherCallbacks.onDragStarted(view);                                                               
3117          }                                                                                                         
3118      }                                                                                                             
3119                                                                                                                    
3120      /**                                                                                                           
3121       * Called when the user stops interacting with the launcher.                                                  
3122       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
3123       */                                                                                                           
3124      protected void onInteractionEnd() {                                                                           
3125          if (mLauncherCallbacks != null) {                                                                         
3126              mLauncherCallbacks.onInteractionEnd();                                                                
3127          }                                                                                                         
3128      }                                                                                                             
3129                                                                                                                    
3130      /**                                                                                                           
3131       * Called when the user starts interacting with the launcher.                                                 
3132       * The possible interactions are:                                                                             
3133       *  - open all apps                                                                                           
3134       *  - reorder an app shortcut, or a widget                                                                    
3135       *  - open the overview mode.                                                                                 
3136       * This is a good time to stop doing things that only make sense                                              
3137       * when the user is on the homescreen and not doing housekeeping.                                             
3138       */                                                                                                           
3139      protected void onInteractionBegin() {                                                                         
3140          if (mLauncherCallbacks != null) {                                                                         
3141              mLauncherCallbacks.onInteractionBegin();                                                              
3142 +        }                                                                                                         
3143 +    }                                                                                                             
3144 +                                                                                                                  
3145 +    /** Updates the interaction state. */                                                                         
3146 +    public void updateInteraction(Workspace.State fromState, Workspace.State toState) {                           
3147 +        // Only update the interacting state if we are transitioning to/from a view with an                       
3148 +        // overlay                                                                                                
3149 +        boolean fromStateWithOverlay;                                                                             
3150 +        boolean toStateWithOverlay;                                                                               
3151 +        if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                       
3152 +            fromStateWithOverlay = fromState != Workspace.State.NORMAL;                                           
3153 +            toStateWithOverlay = toState != Workspace.State.NORMAL;                                               
3154 +        } else {                                                                                                  
3155 +            fromStateWithOverlay = fromState != Workspace.State.NORMAL &&                                         
3156 +                    fromState != Workspace.State.NORMAL_HIDDEN;                                                   
3157 +            toStateWithOverlay = toState != Workspace.State.NORMAL &&                                             
3158 +                    toState != Workspace.State.NORMAL_HIDDEN;                                                     
3159 +        }                                                                                                         
3160 +        if (toStateWithOverlay) {                                                                                 
3161 +            onInteractionBegin();                                                                                 
3162 +        } else if (fromStateWithOverlay) {                                                                        
3163 +            onInteractionEnd();                                                                                   
3164          }                                                                                                         
3165      }                                                                                                             
3166                                                                                                                    
3167      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
3168          try {                                                                                                     
3169              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3170              launcherApps.showAppDetailsForProfile(componentName, user);                                           
3171          } catch (SecurityException e) {                                                                           
3172              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3173              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
3174          } catch (ActivityNotFoundException e) {                                                                   
3175              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3176              Log.e(TAG, "Unable to launch settings");                                                              
3177          }                                                                                                         
3178      }                                                                                                             
3179                                                                                                                    
3180      // returns true if the activity was started                                                                   
3181      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
3182              UserHandleCompat user) {                                                                              
3183          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
3184              // System applications cannot be installed. For now, show a toast explaining that.                    
3185              // We may give them the option of disabling apps this way.                                            
3186              int messageId = R.string.uninstall_system_app_text;                                                   
3187              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
3188              return false;                                                                                         
3189          } else {                                                                                                  
3190              String packageName = componentName.getPackageName();                                                  
3191              String className = componentName.getClassName();                                                      
3192              Intent intent = new Intent(                                                                           
3193                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
3194              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
3195                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
3196              if (user != null) {                                                                                   
3197                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
3198              }                                                                                                     
3199              startActivity(intent);                                                                                
3200              return true;                                                                                          
3201          }                                                                                                         
3202      }                                                                                                             
3203                                                                                                                    
3204      boolean startActivity(View v, Intent intent, Object tag) {                                                    
3205          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
3206          try {                                                                                                     
3207              // Only launch using the new animation if the shortcut has not opted out (this is a                   
3208              // private contract between launcher and may be ignored in the future).                               
3209              boolean useLaunchAnimation = (v != null) &&                                                           
3210                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
3211              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3212              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
3213                                                                                                                    
3214              UserHandleCompat user = null;                                                                         
3215              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
3216                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
3217                  user = userManager.getUserForSerialNumber(serialNumber);                                          
3218              }                                                                                                     
3219                                                                                                                    
3220              Bundle optsBundle = null;                                                                             
3221 -            if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                                
3222 -                // On pre-L devices, we use the scale up transition.                                              
3223 -                // Otherwise we use system default.                                                               
3224 -                ActivityOptions opts =                                                                            
3225 -                        ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵






3226 -                optsBundle = opts.toBundle();                                                                     
3227 +            if (useLaunchAnimation) {                                                                             
3228 +                ActivityOptions opts = null;                                                                      
3229 +                if (sClipRevealMethod != null) {                                                                  
3230 +                    // TODO: call method directly when Launcher3 can depend on M APIs                             
3231 +                    int left = 0, top = 0;                                                                        
3232 +                    int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                             
3233 +                    if (v instanceof TextView) {                                                                  
3234 +                        // Launch from center of icon, not entire view                                            
3235 +                        Drawable icon = Workspace.getTextViewIcon((TextView) v);                                  
3236 +                        if (icon != null) {                                                                       
3237 +                            Rect bounds = icon.getBounds();                                                       
3238 +                            left = (width - bounds.width()) / 2;                                                  
3239 +                            top = v.getPaddingTop();                                                              
3240 +                            width = bounds.width();                                                               
3241 +                            height = bounds.height();                                                             
3242 +                        }                                                                                         
3243 +                    }                                                                                             
3244 +                    try {                                                                                         
3245 +                        opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                                
3246 +                                left, top, width, height);                                                        
3247 +                    } catch (IllegalAccessException e) {                                                          
3248 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3249 +                        sClipRevealMethod = null;                                                                 
3250 +                    } catch (InvocationTargetException e) {                                                       
3251 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3252 +                        sClipRevealMethod = null;                                                                 
3253 +                    }                                                                                             
3254 +                }                                                                                                 
3255 +                if (opts == null && !Utilities.isLmpOrAbove()) {                                                  
3256 +                    opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                          
3257 +                                    v.getMeasuredWidth(), v.getMeasuredHeight());                                 
3258 +                }                                                                                                 
3259 +                optsBundle = opts != null ? opts.toBundle() : null;                                               
3260              }                                                                                                     
3261                                                                                                                    
3262              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
3263                  // Could be launching some bookkeeping activity                                                   
3264                  startActivity(intent, optsBundle);                                                                
3265              } else {                                                                                              
3266                  // TODO Component can be null when shortcuts are supported for secondary user                     
3267                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
3268                          intent.getSourceBounds(), optsBundle);                                                    
3269              }                                                                                                     
3270              return true;                                                                                          
3271          } catch (SecurityException e) {                                                                           
3272              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3273              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
3274                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
3275                      "or use the exported attribute for this activity. "                                           
3276                      + "tag="+ tag + " intent=" + intent, e);                                                      
3277          }                                                                                                         
3278          return false;                                                                                             
3279      }                                                                                                             
3280                                                                                                                    
3281      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
3282          boolean success = false;                                                                                  
3283          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
3284              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
3285              return false;                                                                                         
3286          }                                                                                                         
3287          try {                                                                                                     
3288              success = startActivity(v, intent, tag);                                                              
3289          } catch (ActivityNotFoundException e) {                                                                   
3290              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3291              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
3292          }                                                                                                         
3293          return success;                                                                                           
3294      }                                                                                                             
3295                                                                                                                    
3296      /**                                                                                                           
3297       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
3298       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
3299       */                                                                                                           
3300      private void copyFolderIconToImage(FolderIcon fi) {                                                           
3301          final int width = fi.getMeasuredWidth();                                                                  
3302          final int height = fi.getMeasuredHeight();                                                                
3303                                                                                                                    
3304          // Lazy load ImageView, Bitmap and Canvas                                                                 
3305          if (mFolderIconImageView == null) {                                                                       
3306              mFolderIconImageView = new ImageView(this);                                                           
3307          }                                                                                                         
3308          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3309                  mFolderIconBitmap.getHeight() != height) {                                                        
3310              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3311              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3312          }                                                                                                         
3313                                                                                                                    
3314          DragLayer.LayoutParams lp;                                                                                
3315          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3316              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3317          } else {                                                                                                  
3318              lp = new DragLayer.LayoutParams(width, height);                                                       
3319          }                                                                                                         
3320                                                                                                                    
3321          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3322          // view size by this scale factor.                                                                        
3323          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3324          lp.customPosition = true;                                                                                 
3325          lp.x = mRectForFolderAnimation.left;                                                                      
3326          lp.y = mRectForFolderAnimation.top;                                                                       
3327          lp.width = (int) (scale * width);                                                                         
3328          lp.height = (int) (scale * height);                                                                       
3329                                                                                                                    
3330          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3331          fi.draw(mFolderIconCanvas);                                                                               
3332          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3333          if (fi.getFolder() != null) {                                                                             
3334              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3335              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3336          }                                                                                                         
3337          // Just in case this image view is still in the drag layer from a previous animation,                     
3338          // we remove it and re-add it.                                                                            
3339          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3340              mDragLayer.removeView(mFolderIconImageView);                                                          
3341          }                                                                                                         
3342          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3343          if (fi.getFolder() != null) {                                                                             
3344              fi.getFolder().bringToFront();                                                                        
3345          }                                                                                                         
3346      }                                                                                                             
3347                                                                                                                    
3348      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3349          if (fi == null) return;                                                                                   
3350          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3351          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3352          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3353                                                                                                                    
3354          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3355          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3356              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3357              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3358              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3359          }                                                                                                         
3360                                                                                                                    
3361          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3362          copyFolderIconToImage(fi);                                                                                
3363          fi.setVisibility(View.INVISIBLE);                                                                         
3364                                                                                                                    
3365          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3366                  scaleX, scaleY);                                                                                  
3367          if (Utilities.isLmpOrAbove()) {                                                                           
3368              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3369          }                                                                                                         
3370          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3371          oa.start();                                                                                               
3372      }                                                                                                             
3373                                                                                                                    
3374      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3375          if (fi == null) return;                                                                                   
3376          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3377          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3378          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3379                                                                                                                    
3380          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3381                                                                                                                    
3382          // We remove and re-draw the FolderIcon in-case it has changed                                            
3383          mDragLayer.removeView(mFolderIconImageView);                                                              
3384          copyFolderIconToImage(fi);                                                                                
3385          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3386                  scaleX, scaleY);                                                                                  
3387          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3388          oa.addListener(new AnimatorListenerAdapter() {                                                            
3389              @Override                                                                                             
3390              public void onAnimationEnd(Animator animation) {                                                      
3391                  if (cl != null) {                                                                                 
3392                      cl.clearFolderLeaveBehind();                                                                  
3393                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3394                      mDragLayer.removeView(mFolderIconImageView);                                                  
3395                      fi.setVisibility(View.VISIBLE);                                                               
3396                  }                                                                                                 
3397              }                                                                                                     
3398          });                                                                                                       
3399          oa.start();                                                                                               
3400      }                                                                                                             
3401                                                                                                                    
3402      /**                                                                                                           
3403       * Opens the user folder described by the specified tag. The opening of the folder                            
3404       * is animated relative to the specified View. If the View is null, no animation                              
3405       * is played.                                                                                                 
3406       *                                                                                                            
3407       * @param folderInfo The FolderInfo describing the folder to open.                                            
3408       */                                                                                                           
3409      public void openFolder(FolderIcon folderIcon) {                                                               
3410          Folder folder = folderIcon.getFolder();                                                                   
3411 +        Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                               
3412 +        if (openFolder != null && openFolder != folder) {                                                         
3413 +            // Close any open folder before opening a folder.                                                     
3414 +            closeFolder();                                                                                        
3415 +        }                                                                                                         
3416 +                                                                                                                  
3417          FolderInfo info = folder.mInfo;                                                                           
3418                                                                                                                    
3419          info.opened = true;                                                                                       
3420 +                                                                                                                  
3421 +        // While the folder is open, the position of the icon cannot change.                                      
3422 +        ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                              
3423                                                                                                                    
3424          // Just verify that the folder hasn't already been added to the DragLayer.                                
3425          // There was a one-off crash where the folder had a parent already.                                       
3426          if (folder.getParent() == null) {                                                                         
3427              mDragLayer.addView(folder);                                                                           
3428              mDragController.addDropTarget((DropTarget) folder);                                                   
3429          } else {                                                                                                  
3430              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3431                      folder.getParent() + ").");                                                                   
3432          }                                                                                                         
3433          folder.animateOpen();                                                                                     
3434          growAndFadeOutFolderIcon(folderIcon);                                                                     
3435                                                                                                                    
3436          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3437          // the workspace items                                                                                    
3438          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3439          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3440      }                                                                                                             
3441                                                                                                                    
3442      public void closeFolder() {                                                                                   
3443          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3444          if (folder != null) {                                                                                     
3445              if (folder.isEditingName()) {                                                                         
3446                  folder.dismissEditingName();                                                                      
3447              }                                                                                                     
3448              closeFolder(folder);                                                                                  
3449          }                                                                                                         
3450      }                                                                                                             
3451                                                                                                                    
3452 -    void closeFolder(Folder folder) {                                                                             
3453 +    public void closeFolder(Folder folder) {                                                                      
3454          folder.getInfo().opened = false;                                                                          
3455                                                                                                                    
3456          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3457          if (parent != null) {                                                                                     
3458              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3459              shrinkAndFadeInFolderIcon(fi);                                                                        
3460 +            if (fi != null) {                                                                                     
3461 +                ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                               
3462 +            }                                                                                                     
3463          }                                                                                                         
3464          folder.animateClosed();                                                                                   
3465                                                                                                                    
3466          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3467          // longer occludeds the workspace items                                                                   
3468          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3469      }                                                                                                             
3470                                                                                                                    
3471      public boolean onLongClick(View v) {                                                                          
3472          if (!isDraggingEnabled()) return false;                                                                   
3473          if (isWorkspaceLocked()) return false;                                                                    
3474          if (mState != State.WORKSPACE) return false;                                                              
3475                                                                                                                    
3476          if (v instanceof Workspace) {                                                                             
3477              if (!mWorkspace.isInOverviewMode()) {                                                                 
3478 -                if (mWorkspace.enterOverviewMode()) {                                                             
3479 +                if (!mWorkspace.isTouchActive()) {                                                                
3480 +                    showOverviewMode(true);                                                                       
3481                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3482                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3483                      return true;                                                                                  
3484                  } else {                                                                                          
3485                      return false;                                                                                 
3486                  }                                                                                                 
3487              } else {                                                                                              
3488                  return false;                                                                                     
3489              }                                                                                                     
3490          }                                                                                                         
3491                                                                                                                    
3492          CellLayout.CellInfo longClickCellInfo = null;                                                             
3493          View itemUnderLongClick = null;                                                                           
3494          if (v.getTag() instanceof ItemInfo) {                                                                     
3495              ItemInfo info = (ItemInfo) v.getTag();                                                                
3496 -            longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3497 +            longClickCellInfo = new CellLayout.CellInfo(v, info);                                                 
3498              itemUnderLongClick = longClickCellInfo.cell;                                                          
3499              resetAddInfo();                                                                                       
3500          }                                                                                                         
3501                                                                                                                    
3502          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3503          // on hotseat items.                                                                                      
3504          final boolean inHotseat = isHotseatLayout(v);                                                             
3505 -        boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3506 -        if (allowLongPress && !mDragController.isDragging()) {                                                    
3507 +        if (!mDragController.isDragging()) {                                                                      
3508              if (itemUnderLongClick == null) {                                                                     
3509                  // User long pressed on empty space                                                               
3510                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3511                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3512                  if (mWorkspace.isInOverviewMode()) {                                                              
3513                      mWorkspace.startReordering(v);                                                                
3514                  } else {                                                                                          
3515 -                    mWorkspace.enterOverviewMode();                                                               
3516 +                    showOverviewMode(true);                                                                       
3517                  }                                                                                                 
3518              } else {                                                                                              
3519                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3520                          mHotseat.getOrderInHotseat(                                                               
3521                                  longClickCellInfo.cellX,                                                          
3522                                  longClickCellInfo.cellY));                                                        
3523                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3524                      // User long pressed on an item                                                               
3525                      mWorkspace.startDrag(longClickCellInfo);                                                      
3526                  }                                                                                                 
3527              }                                                                                                     
3528          }                                                                                                         
3529          return true;                                                                                              
3530      }                                                                                                             
3531                                                                                                                    
3532      boolean isHotseatLayout(View layout) {                                                                        
3533          return mHotseat != null && layout != null &&                                                              
3534                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3535      }                                                                                                             
3536                                                                                                                    
3537      /**                                                                                                           
3538       * Returns the CellLayout of the specified container at the specified screen.                                 
3539       */                                                                                                           
3540 -    CellLayout getCellLayout(long container, long screenId) {                                                     
3541 +    public CellLayout getCellLayout(long container, long screenId) {                                              
3542          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3543              if (mHotseat != null) {                                                                               
3544                  return mHotseat.getLayout();                                                                      
3545              } else {                                                                                              
3546                  return null;                                                                                      
3547              }                                                                                                     
3548          } else {                                                                                                  
3549 -            return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3550 -        }                                                                                                         
3551 -    }                                                                                                             
3552 -                                                                                                                  
3553 +            return mWorkspace.getScreenWithId(screenId);                                                          
3554 +        }                                                                                                         
3555 +    }                                                                                                             
3556 +                                                                                                                  
3557 +    /**                                                                                                           
3558 +     * For overridden classes.                                                                                    
3559 +     */                                                                                                           
3560      public boolean isAllAppsVisible() {                                                                           
3561 -        return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3562 -    }                                                                                                             
3563 -                                                                                                                  
3564 -    private void setWorkspaceBackground(boolean workspace) {                                                      
3565 -        mLauncherView.setBackground(workspace ?                                                                   
3566 -                mWorkspaceBackgroundDrawable : null);                                                             
3567 +        return isAppsViewVisible();                                                                               
3568 +    }                                                                                                             
3569 +                                                                                                                  
3570 +    public boolean isAppsViewVisible() {                                                                          
3571 +        return (mState == State.APPS) || (mOnResumeState == State.APPS);                                          
3572 +    }                                                                                                             
3573 +                                                                                                                  
3574 +    public boolean isWidgetsViewVisible() {                                                                       
3575 +        return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                                    
3576 +    }                                                                                                             
3577 +                                                                                                                  
3578 +    private void setWorkspaceBackground(int background) {                                                         
3579 +        switch (background) {                                                                                     
3580 +            case WORKSPACE_BACKGROUND_TRANSPARENT:                                                                
3581 +                getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));                          
3582 +                break;                                                                                            
3583 +            case WORKSPACE_BACKGROUND_BLACK:                                                                      
3584 +                getWindow().setBackgroundDrawable(null);                                                          
3585 +                break;                                                                                            
3586 +            default:                                                                                              
3587 +                getWindow().setBackgroundDrawable(mWorkspaceBackgroundDrawable);                                  
3588 +        }                                                                                                         
3589      }                                                                                                             
3590                                                                                                                    
3591      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3592          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3593          int curflags = getWindow().getAttributes().flags                                                          
3594                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3595          if (wpflags != curflags) {                                                                                
3596              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3597          }                                                                                                         
3598 -        setWorkspaceBackground(visible);                                                                          
3599 -    }                                                                                                             
3600 -                                                                                                                  
3601 -    private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3602 -        if (v instanceof LauncherTransitionable) {                                                                
3603 -            ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3604 -        }                                                                                                         
3605 -    }                                                                                                             
3606 -                                                                                                                  
3607 -    private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3608 -        if (v instanceof LauncherTransitionable) {                                                                
3609 -            ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3610 -        }                                                                                                         
3611 -                                                                                                                  
3612 -        // Update the workspace transition step as well                                                           
3613 -        dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3614 -    }                                                                                                             
3615 -                                                                                                                  
3616 -    private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3617 -        if (v instanceof LauncherTransitionable) {                                                                
3618 -            ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3619 -        }                                                                                                         
3620 -    }                                                                                                             
3621 -                                                                                                                  
3622 -    private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3623 -        if (v instanceof LauncherTransitionable) {                                                                
3624 -            ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3625 -        }                                                                                                         
3626 -                                                                                                                  
3627 -        // Update the workspace transition step as well                                                           
3628 -        dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3629 -    }                                                                                                             
3630 -                                                                                                                  
3631 -    /**                                                                                                           
3632 -     * Things to test when changing the following seven functions.                                                
3633 -     *   - Home from workspace                                                                                    
3634 -     *          - from center screen                                                                              
3635 -     *          - from other screens                                                                              
3636 -     *   - Home from all apps                                                                                     
3637 -     *          - from center screen                                                                              
3638 -     *          - from other screens                                                                              
3639 -     *   - Back from all apps                                                                                     
3640 -     *          - from center screen                                                                              
3641 -     *          - from other screens                                                                              
3642 -     *   - Launch app from workspace and quit                                                                     
3643 -     *          - with back                                                                                       
3644 -     *          - with home                                                                                       
3645 -     *   - Launch app from all apps and quit                                                                      
3646 -     *          - with back                                                                                       
3647 -     *          - with home                                                                                       
3648 -     *   - Go to a screen that's not the default, then all                                                        
3649 -     *     apps, and launch and app, and go back                                                                  
3650 -     *          - with back                                                                                       
3651 -     *          -with home                                                                                        
3652 -     *   - On workspace, long press power and go back                                                             
3653 -     *          - with back                                                                                       
3654 -     *          - with home                                                                                       
3655 -     *   - On all apps, long press power and go back                                                              
3656 -     *          - with back                                                                                       
3657 -     *          - with home                                                                                       
3658 -     *   - On workspace, power off                                                                                
3659 -     *   - On all apps, power off                                                                                 
3660 -     *   - Launch an app and turn off the screen while in that app                                                
3661 -     *          - Go back with home key                                                                           
3662 -     *          - Go back with back key  TODO: make this not go to workspace                                      
3663 -     *          - From all apps                                                                                   
3664 -     *          - From workspace                                                                                  
3665 -     *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3666 -     *          - From all apps                                                                                   
3667 -     *          - From the center workspace                                                                       
3668 -     *          - From another workspace                                                                          
3669 -     */                                                                                                           
3670 -                                                                                                                  
3671 -    /**                                                                                                           
3672 -     * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3673 -     * Assumes that the view to show is anchored at either the very top or very bottom                            
3674 -     * of the screen.                                                                                             
3675 -     */                                                                                                           
3676 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3677 -        AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3678 -        showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3679 -    }                                                                                                             
3680 -                                                                                                                  
3681 -    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3682 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3683 -                                         final AppsCustomizePagedView.ContentType contentType) {                  
3684 -        if (mStateAnimation != null) {                                                                            
3685 -            mStateAnimation.setDuration(0);                                                                       
3686 -            mStateAnimation.cancel();                                                                             
3687 -            mStateAnimation = null;                                                                               
3688 -        }                                                                                                         
3689 -                                                                                                                  
3690 -        boolean material = Utilities.isLmpOrAbove();                                                              
3691 -                                                                                                                  
3692 -        final Resources res = getResources();                                                                     
3693 -                                                                                                                  
3694 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3695 -        final int itemsAlphaStagger =                                                                             
3696 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3697 -                                                                                                                  
3698 -        final View fromView = mWorkspace;                                                                         
3699 -        final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3700 -                                                                                                                  
3701 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3702 -                                                                                                                  
3703 -        Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3704 -                Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3705 -        Animator workspaceAnim =                                                                                  
3706 -                mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3707 -        if (!LauncherAppState.isDisableAllApps()                                                                  
3708 -                || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3709 -            // Set the content type for the all apps/widgets space                                                
3710 -            mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3711 -        }                                                                                                         
3712 -                                                                                                                  
3713 -        // If for some reason our views aren't initialized, don't animate                                         
3714 -        boolean initialized = getAllAppsButton() != null;                                                         
3715 -                                                                                                                  
3716 -        if (animated && initialized) {                                                                            
3717 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3718 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3719 -                    toView.findViewById(R.id.apps_customize_pane_content);                                        
3720 -                                                                                                                  
3721 -            final View page = content.getPageAt(content.getCurrentPage());                                        
3722 -            final View revealView = toView.findViewById(R.id.fake_page);                                          
3723 -                                                                                                                  
3724 -            final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3725 -            if (isWidgetTray) {                                                                                   
3726 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3727 -            } else {                                                                                              
3728 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3729 -            }                                                                                                     
3730 -                                                                                                                  
3731 -            // Hide the real page background, and swap in the fake one                                            
3732 -            content.setPageBackgroundsVisible(false);                                                             
3733 -            revealView.setVisibility(View.VISIBLE);                                                               
3734 -            // We need to hide this view as the animation start will be posted.                                   
3735 -            revealView.setAlpha(0);                                                                               
3736 -                                                                                                                  
3737 -            int width = revealView.getMeasuredWidth();                                                            
3738 -            int height = revealView.getMeasuredHeight();                                                          
3739 -            float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3740 -                                                                                                                  
3741 -            revealView.setTranslationY(0);                                                                        
3742 -            revealView.setTranslationX(0);                                                                        
3743 -                                                                                                                  
3744 -            // Get the y delta between the center of the page and the center of the all apps button               
3745 -            int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3746 -                    getAllAppsButton(), null);                                                                    
3747 -                                                                                                                  
3748 -            float alpha = 0;                                                                                      
3749 -            float xDrift = 0;                                                                                     
3750 -            float yDrift = 0;                                                                                     
3751 -            if (material) {                                                                                       
3752 -                alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3753 -                yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3754 -                xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3755 -            } else {                                                                                              
3756 -                yDrift = 2 * height / 3;                                                                          
3757 -                xDrift = 0;                                                                                       
3758 -            }                                                                                                     
3759 -            final float initAlpha = alpha;                                                                        
3760 -                                                                                                                  
3761 -            layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3762 -            PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3763 -            PropertyValuesHolder panelDriftY =                                                                    
3764 -                    PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3765 -            PropertyValuesHolder panelDriftX =                                                                    
3766 -                    PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3767 -                                                                                                                  
3768 -            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3769 -                    panelAlpha, panelDriftY, panelDriftX);                                                        
3770 -                                                                                                                  
3771 -            panelAlphaAndDrift.setDuration(revealDuration);                                                       
3772 -            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3773 -                                                                                                                  
3774 -            mStateAnimation.play(panelAlphaAndDrift);                                                             
3775 -                                                                                                                  
3776 -            if (page != null) {                                                                                   
3777 -                page.setVisibility(View.VISIBLE);                                                                 
3778 -                layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3779 -                                                                                                                  
3780 -                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3781 -                page.setTranslationY(yDrift);                                                                     
3782 -                pageDrift.setDuration(revealDuration);                                                            
3783 -                pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3784 -                pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3785 -                mStateAnimation.play(pageDrift);                                                                  
3786 -                                                                                                                  
3787 -                page.setAlpha(0f);                                                                                
3788 -                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3789 -                itemsAlpha.setDuration(revealDuration);                                                           
3790 -                itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3791 -                itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3792 -                mStateAnimation.play(itemsAlpha);                                                                 
3793 -            }                                                                                                     
3794 -                                                                                                                  
3795 -            View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3796 -            pageIndicators.setAlpha(0.01f);                                                                       
3797 -            ObjectAnimator indicatorsAlpha =                                                                      
3798 -                    ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3799 -            indicatorsAlpha.setDuration(revealDuration);                                                          
3800 -            mStateAnimation.play(indicatorsAlpha);                                                                
3801 -                                                                                                                  
3802 -            if (material) {                                                                                       
3803 -                final View allApps = getAllAppsButton();                                                          
3804 -                int allAppsButtonSize = LauncherAppState.getInstance().                                           
3805 -                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3806 -                float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3807 -                Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3808 -                                height / 2, startRadius, revealRadius);                                           
3809 -                reveal.setDuration(revealDuration);                                                               
3810 -                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3811 -                                                                                                                  
3812 -                reveal.addListener(new AnimatorListenerAdapter() {                                                
3813 -                    public void onAnimationStart(Animator animation) {                                            
3814 -                        if (!isWidgetTray) {                                                                      
3815 -                            allApps.setVisibility(View.INVISIBLE);                                                
3816 -                        }                                                                                         
3817 -                    }                                                                                             
3818 -                    public void onAnimationEnd(Animator animation) {                                              
3819 -                        if (!isWidgetTray) {                                                                      
3820 -                            allApps.setVisibility(View.VISIBLE);                                                  
3821 -                        }                                                                                         
3822 -                    }                                                                                             
3823 -                });                                                                                               
3824 -                mStateAnimation.play(reveal);                                                                     
3825 -            }                                                                                                     
3826 -                                                                                                                  
3827 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3828 -                @Override                                                                                         
3829 -                public void onAnimationEnd(Animator animation) {                                                  
3830 -                    dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3831 -                    dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3832 -                                                                                                                  
3833 -                    revealView.setVisibility(View.INVISIBLE);                                                     
3834 -                                                                                                                  
3835 -                    for (View v : layerViews.keySet()) {                                                          
3836 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3837 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3838 -                        }                                                                                         
3839 -                    }                                                                                             
3840 -                    content.setPageBackgroundsVisible(true);                                                      
3841 -                                                                                                                  
3842 -                    // Hide the search bar                                                                        
3843 -                    if (mSearchDropTargetBar != null) {                                                           
3844 -                        mSearchDropTargetBar.hideSearchBar(false);                                                
3845 -                    }                                                                                             
3846 -                                                                                                                  
3847 -                    // This can hold unnecessary references to views.                                             
3848 -                    mStateAnimation = null;                                                                       
3849 -                }                                                                                                 
3850 -                                                                                                                  
3851 -            });                                                                                                   
3852 -                                                                                                                  
3853 -            if (workspaceAnim != null) {                                                                          
3854 -                mStateAnimation.play(workspaceAnim);                                                              
3855 -            }                                                                                                     
3856 -                                                                                                                  
3857 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3858 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3859 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
3860 -            final Runnable startAnimRunnable = new Runnable() {                                                   
3861 -                public void run() {                                                                               
3862 -                    // Check that mStateAnimation hasn't changed while                                            
3863 -                    // we waited for a layout/draw pass                                                           
3864 -                    if (mStateAnimation != stateAnimation)                                                        
3865 -                        return;                                                                                   
3866 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3867 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3868 -                                                                                                                  
3869 -                    revealView.setAlpha(initAlpha);                                                               
3870 -                                                                                                                  
3871 -                    for (View v : layerViews.keySet()) {                                                          
3872 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3873 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3874 -                        }                                                                                         
3875 -                    }                                                                                             
3876 -                                                                                                                  
3877 -                    if (Utilities.isLmpOrAbove()) {                                                               
3878 -                        for (View v : layerViews.keySet()) {                                                      
3879 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3880 -                        }                                                                                         
3881 -                    }                                                                                             
3882 -                    mStateAnimation.start();                                                                      
3883 -                }                                                                                                 
3884 -            };                                                                                                    
3885 -            toView.bringToFront();                                                                                
3886 -            toView.setVisibility(View.VISIBLE);                                                                   
3887 -            toView.post(startAnimRunnable);                                                                       
3888 -        } else {                                                                                                  
3889 -            toView.setTranslationX(0.0f);                                                                         
3890 -            toView.setTranslationY(0.0f);                                                                         
3891 -            toView.setScaleX(1.0f);                                                                               
3892 -            toView.setScaleY(1.0f);                                                                               
3893 -            toView.setVisibility(View.VISIBLE);                                                                   
3894 -            toView.bringToFront();                                                                                
3895 -                                                                                                                  
3896 -            if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3897 -                // Hide the search bar                                                                            
3898 -                if (mSearchDropTargetBar != null) {                                                               
3899 -                    mSearchDropTargetBar.hideSearchBar(false);                                                    
3900 -                }                                                                                                 
3901 -            }                                                                                                     
3902 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3903 -            dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3904 -            dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3905 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3906 -            dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3907 -            dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3908 -        }                                                                                                         
3909 -    }                                                                                                             
3910 -                                                                                                                  
3911 -    /**                                                                                                           
3912 -     * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3913 -     * This is the opposite of showAppsCustomizeHelper.                                                           
3914 -     * @param animated If true, the transition will be animated.                                                  
3915 -     */                                                                                                           
3916 -    private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3917 -            final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3918 -                                                                                                                  
3919 -        if (mStateAnimation != null) {                                                                            
3920 -            mStateAnimation.setDuration(0);                                                                       
3921 -            mStateAnimation.cancel();                                                                             
3922 -            mStateAnimation = null;                                                                               
3923 -        }                                                                                                         
3924 -                                                                                                                  
3925 -        boolean material = Utilities.isLmpOrAbove();                                                              
3926 -        Resources res = getResources();                                                                           
3927 -                                                                                                                  
3928 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3929 -        final int itemsAlphaStagger =                                                                             
3930 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3931 -                                                                                                                  
3932 -        final View fromView = mAppsCustomizeTabHost;                                                              
3933 -        final View toView = mWorkspace;                                                                           
3934 -        Animator workspaceAnim = null;                                                                            
3935 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3936 -                                                                                                                  
3937 -        if (toState == Workspace.State.NORMAL) {                                                                  
3938 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3939 -                    toState, animated, layerViews);                                                               
3940 -        } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3941 -                toState == Workspace.State.OVERVIEW) {                                                            
3942 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3943 -                    toState, animated, layerViews);                                                               
3944 -        }                                                                                                         
3945 -                                                                                                                  
3946 -        // If for some reason our views aren't initialized, don't animate                                         
3947 -        boolean initialized = getAllAppsButton() != null;                                                         
3948 -                                                                                                                  
3949 -        if (animated && initialized) {                                                                            
3950 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3951 -            if (workspaceAnim != null) {                                                                          
3952 -                mStateAnimation.play(workspaceAnim);                                                              
3953 -            }                                                                                                     
3954 -                                                                                                                  
3955 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3956 -                    fromView.findViewById(R.id.apps_customize_pane_content);                                      
3957 -                                                                                                                  
3958 -            final View page = content.getPageAt(content.getNextPage());                                           
3959 -                                                                                                                  
3960 -            // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3961 -            int count = content.getChildCount();                                                                  
3962 -            for (int i = 0; i < count; i++) {                                                                     
3963 -                View child = content.getChildAt(i);                                                               
3964 -                if (child != page) {                                                                              
3965 -                    child.setVisibility(View.INVISIBLE);                                                          
3966 -                }                                                                                                 
3967 -            }                                                                                                     
3968 -            final View revealView = fromView.findViewById(R.id.fake_page);                                        
3969 -                                                                                                                  
3970 -            // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3971 -            // don't perform all these no-op animations. In particularly, this was causing                        
3972 -            // the all-apps button to pop in and out.                                                             
3973 -            if (fromView.getVisibility() == View.VISIBLE) {                                                       
3974 -                AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3975 -                final boolean isWidgetTray =                                                                      
3976 -                        contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3977 -                                                                                                                  
3978 -                if (isWidgetTray) {                                                                               
3979 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3980 -                } else {                                                                                          
3981 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3982 -                }                                                                                                 
3983 -                                                                                                                  
3984 -                int width = revealView.getMeasuredWidth();                                                        
3985 -                int height = revealView.getMeasuredHeight();                                                      
3986 -                float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3987 -                                                                                                                  
3988 -                // Hide the real page background, and swap in the fake one                                        
3989 -                revealView.setVisibility(View.VISIBLE);                                                           
3990 -                content.setPageBackgroundsVisible(false);                                                         
3991 -                                                                                                                  
3992 -                final View allAppsButton = getAllAppsButton();                                                    
3993 -                revealView.setTranslationY(0);                                                                    
3994 -                int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3995 -                        allAppsButton, null);                                                                     
3996 -                                                                                                                  
3997 -                float xDrift = 0;                                                                                 
3998 -                float yDrift = 0;                                                                                 
3999 -                if (material) {                                                                                   
4000 -                    yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
4001 -                    xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
4002 -                } else {                                                                                          
4003 -                    yDrift = 2 * height / 3;                                                                      
4004 -                    xDrift = 0;                                                                                   
4005 -                }                                                                                                 
4006 -                                                                                                                  
4007 -                layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
4008 -                TimeInterpolator decelerateInterpolator = material ?                                              
4009 -                        new LogDecelerateInterpolator(100, 0) :                                                   
4010 -                        new DecelerateInterpolator(1f);                                                           
4011 -                                                                                                                  
4012 -                // The vertical motion of the apps panel should be delayed by one frame                           
4013 -                // from the conceal animation in order to give the right feel. We correpsondingly                 
4014 -                // shorten the duration so that the slide and conceal end at the same time.                       
4015 -                ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
4016 -                        0, yDrift);                                                                               
4017 -                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
4018 -                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
4019 -                panelDriftY.setInterpolator(decelerateInterpolator);                                              
4020 -                mStateAnimation.play(panelDriftY);                                                                
4021 -                                                                                                                  
4022 -                ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
4023 -                        0, xDrift);                                                                               
4024 -                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
4025 -                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
4026 -                panelDriftX.setInterpolator(decelerateInterpolator);                                              
4027 -                mStateAnimation.play(panelDriftX);                                                                
4028 -                                                                                                                  
4029 -                if (isWidgetTray || !material) {                                                                  
4030 -                    float finalAlpha = material ? 0.4f : 0f;                                                      
4031 -                    revealView.setAlpha(1f);                                                                      
4032 -                    ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
4033 -                            1f, finalAlpha);                                                                      
4034 -                    panelAlpha.setDuration(material ? revealDuration : 150);                                      
4035 -                    panelAlpha.setInterpolator(decelerateInterpolator);                                           
4036 -                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
4037 -                    mStateAnimation.play(panelAlpha);                                                             
4038 -                }                                                                                                 
4039 -                                                                                                                  
4040 -                if (page != null) {                                                                               
4041 -                    layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
4042 -                                                                                                                  
4043 -                    ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
4044 -                            0, yDrift);                                                                           
4045 -                    page.setTranslationY(0);                                                                      
4046 -                    pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
4047 -                    pageDrift.setInterpolator(decelerateInterpolator);                                            
4048 -                    pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
4049 -                    mStateAnimation.play(pageDrift);                                                              
4050 -                                                                                                                  
4051 -                    page.setAlpha(1f);                                                                            
4052 -                    ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
4053 -                    itemsAlpha.setDuration(100);                                                                  
4054 -                    itemsAlpha.setInterpolator(decelerateInterpolator);                                           
4055 -                    mStateAnimation.play(itemsAlpha);                                                             
4056 -                }                                                                                                 
4057 -                                                                                                                  
4058 -                View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
4059 -                pageIndicators.setAlpha(1f);                                                                      
4060 -                ObjectAnimator indicatorsAlpha =                                                                  
4061 -                        LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
4062 -                indicatorsAlpha.setDuration(revealDuration);                                                      
4063 -                indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
4064 -                mStateAnimation.play(indicatorsAlpha);                                                            
4065 -                                                                                                                  
4066 -                width = revealView.getMeasuredWidth();                                                            
4067 -                                                                                                                  
4068 -                if (material) {                                                                                   
4069 -                    if (!isWidgetTray) {                                                                          
4070 -                        allAppsButton.setVisibility(View.INVISIBLE);                                              
4071 -                    }                                                                                             
4072 -                    int allAppsButtonSize = LauncherAppState.getInstance().                                       
4073 -                            getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
4074 -                    float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
4075 -                    Animator reveal =                                                                             
4076 -                            LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
4077 -                                    height / 2, revealRadius, finalRadius);                                       
4078 -                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
4079 -                    reveal.setDuration(revealDuration);                                                           
4080 -                    reveal.setStartDelay(itemsAlphaStagger);                                                      
4081 -                                                                                                                  
4082 -                    reveal.addListener(new AnimatorListenerAdapter() {                                            
4083 -                        public void onAnimationEnd(Animator animation) {                                          
4084 -                            revealView.setVisibility(View.INVISIBLE);                                             
4085 -                            if (!isWidgetTray) {                                                                  
4086 -                                allAppsButton.setVisibility(View.VISIBLE);                                        
4087 -                            }                                                                                     
4088 -                        }                                                                                         
4089 -                    });                                                                                           
4090 -                                                                                                                  
4091 -                    mStateAnimation.play(reveal);                                                                 
4092 -                }                                                                                                 
4093 -                                                                                                                  
4094 -                dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
4095 -                dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
4096 -                mAppsCustomizeContent.stopScrolling();                                                            
4097 -            }                                                                                                     
4098 -                                                                                                                  
4099 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
4100 -                @Override                                                                                         
4101 -                public void onAnimationEnd(Animator animation) {                                                  
4102 -                    fromView.setVisibility(View.GONE);                                                            
4103 -                    dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
4104 -                    dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
4105 -                    if (onCompleteRunnable != null) {                                                             
4106 -                        onCompleteRunnable.run();                                                                 
4107 -                    }                                                                                             
4108 -                                                                                                                  
4109 -                    for (View v : layerViews.keySet()) {                                                          
4110 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
4111 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
4112 -                        }                                                                                         
4113 -                    }                                                                                             
4114 -                                                                                                                  
4115 -                    content.setPageBackgroundsVisible(true);                                                      
4116 -                    // Unhide side pages                                                                          
4117 -                    int count = content.getChildCount();                                                          
4118 -                    for (int i = 0; i < count; i++) {                                                             
4119 -                        View child = content.getChildAt(i);                                                       
4120 -                        child.setVisibility(View.VISIBLE);                                                        
4121 -                    }                                                                                             
4122 -                                                                                                                  
4123 -                    // Reset page transforms                                                                      
4124 -                    if (page != null) {                                                                           
4125 -                        page.setTranslationX(0);                                                                  
4126 -                        page.setTranslationY(0);                                                                  
4127 -                        page.setAlpha(1);                                                                         
4128 -                    }                                                                                             
4129 -                    content.setCurrentPage(content.getNextPage());                                                
4130 -                                                                                                                  
4131 -                    mAppsCustomizeContent.updateCurrentPageScroll();                                              
4132 -                                                                                                                  
4133 -                    // This can hold unnecessary references to views.                                             
4134 -                    mStateAnimation = null;                                                                       
4135 -                }                                                                                                 
4136 -            });                                                                                                   
4137 -                                                                                                                  
4138 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
4139 -            final Runnable startAnimRunnable = new Runnable() {                                                   
4140 -                public void run() {                                                                               
4141 -                    // Check that mStateAnimation hasn't changed while                                            
4142 -                    // we waited for a layout/draw pass                                                           
4143 -                    if (mStateAnimation != stateAnimation)                                                        
4144 -                        return;                                                                                   
4145 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
4146 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
4147 -                                                                                                                  
4148 -                    for (View v : layerViews.keySet()) {                                                          
4149 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
4150 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
4151 -                        }                                                                                         
4152 -                    }                                                                                             
4153 -                                                                                                                  
4154 -                    if (Utilities.isLmpOrAbove()) {                                                               
4155 -                        for (View v : layerViews.keySet()) {                                                      
4156 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
4157 -                        }                                                                                         
4158 -                    }                                                                                             
4159 -                    mStateAnimation.start();                                                                      
4160 -                }                                                                                                 
4161 -            };                                                                                                    
4162 -            fromView.post(startAnimRunnable);                                                                     
4163 -        } else {                                                                                                  
4164 -            fromView.setVisibility(View.GONE);                                                                    
4165 -            dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
4166 -            dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
4167 -            dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
4168 -            dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
4169 -            dispatchOnLauncherTransitionStart(toView, animated, true);                                            
4170 -            dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
4171 -        }                                                                                                         
4172 +        setWorkspaceBackground(visible ? WORKSPACE_BACKGROUND_GRADIENT : WORKSPACE_BACKGROUND_BLACK);             
4173      }                                                                                                             
4174                                                                                                                    
4175      @Override                                                                                                     
4176      public void onTrimMemory(int level) {                                                                         
4177          super.onTrimMemory(level);                                                                                
4178          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
4179              // The widget preview db can result in holding onto over                                              
4180              // 3MB of memory for caching which isn't necessary.                                                   
4181              SQLiteDatabase.releaseMemory();                                                                       
4182                                                                                                                    
4183              // This clears all widget bitmaps from the widget tray                                                
4184 -            if (mAppsCustomizeTabHost != null) {                                                                  
4185 -                mAppsCustomizeTabHost.trimMemory();                                                               
4186 -            }                                                                                                     
4187 +            // TODO(hyunyoungs)                                                                                   
4188          }                                                                                                         
4189          if (mLauncherCallbacks != null) {                                                                         
4190              mLauncherCallbacks.onTrimMemory(level);                                                               
4191          }                                                                                                         
4192      }                                                                                                             
4193                                                                                                                    
4194 -    protected void showWorkspace(boolean animated) {                                                              
4195 -        showWorkspace(animated, null);                                                                            
4196 -    }                                                                                                             
4197 -                                                                                                                  
4198 -    protected void showWorkspace() {                                                                              
4199 -        showWorkspace(true);                                                                                      
4200 -    }                                                                                                             
4201 -                                                                                                                  
4202 -    void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
4203 -        if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
4204 +    @Override                                                                                                     
4205 +    public void onStateTransitionHideSearchBar() {                                                                
4206 +        // Hide the search bar                                                                                    
4207 +        if (mSearchDropTargetBar != null) {                                                                       
4208 +            mSearchDropTargetBar.hideSearchBar(false /* animated */);                                             
4209 +        }                                                                                                         
4210 +    }                                                                                                             
4211 +                                                                                                                  
4212 +    public void showWorkspace(boolean animated) {                                                                 
4213 +        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null,                   
4214 +                true);                                                                                            
4215 +    }                                                                                                             
4216 +                                                                                                                  
4217 +    public void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                    
4218 +        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                         
4219 +                onCompleteRunnable, true);                                                                        
4220 +    }                                                                                                             
4221 +                                                                                                                  
4222 +    protected void showWorkspace(int snapToPage, boolean animated) {                                              
4223 +        showWorkspace(snapToPage, animated, null, true);                                                          
4224 +    }                                                                                                             
4225 +                                                                                                                  
4226 +    void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable,                             
4227 +            boolean notifyLauncherCallbacks) {                                                                    
4228 +        boolean changed = mState != State.WORKSPACE ||                                                            
4229 +                mWorkspace.getState() != Workspace.State.NORMAL;                                                  
4230 +        if (changed) {                                                                                            
4231              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
4232              mWorkspace.setVisibility(View.VISIBLE);                                                               
4233 -            hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
4234 +            mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,                   
4235 +                    snapToPage, animated, onCompleteRunnable);                                                    
4236                                                                                                                    
4237              // Show the search bar (only animate if we were showing the drop target bar in spring                 
4238              // loaded mode)                                                                                       
4239              if (mSearchDropTargetBar != null) {                                                                   
4240                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
4241              }                                                                                                     
4242                                                                                                                    
4243              // Set focus to the AppsCustomize button                                                              
4244              if (mAllAppsButton != null) {                                                                         
4245                  mAllAppsButton.requestFocus();                                                                    
4246              }                                                                                                     
4247          }                                                                                                         
4248                                                                                                                    
4249          // Change the state *after* we've called all the transition code                                          
4250          mState = State.WORKSPACE;                                                                                 
4251                                                                                                                    
4252          // Resume the auto-advance of widgets                                                                     
4253          mUserPresent = true;                                                                                      
4254 -        updateRunning();                                                                                          
4255 +        updateAutoAdvanceState();                                                                                 
4256 +                                                                                                                  
4257 +        if (changed) {                                                                                            
4258 +            // Send an accessibility event to announce the context change                                         
4259 +            getWindow().getDecorView()                                                                            
4260 +                    .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                        
4261 +            if (notifyLauncherCallbacks) {                                                                        
4262 +                // Dismiss all apps when the workspace is shown                                                   
4263 +                if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {                
4264 +                    mLauncherCallbacks.onAllAppsHidden();                                                         
4265 +                }                                                                                                 
4266 +            }                                                                                                     
4267 +        }                                                                                                         
4268 +    }                                                                                                             
4269 +                                                                                                                  
4270 +    void showOverviewMode(boolean animated) {                                                                     
4271 +        mWorkspace.setVisibility(View.VISIBLE);                                                                   
4272 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,                     
4273 +                WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,                               
4274 +                null /* onCompleteRunnable */);                                                                   
4275 +        mState = State.WORKSPACE;                                                                                 
4276 +    }                                                                                                             
4277 +                                                                                                                  
4278 +    /**                                                                                                           
4279 +     * Shows the apps view.                                                                                       
4280 +     */                                                                                                           
4281 +    void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps) {                    
4282 +        if (resetListToTop) {                                                                                     
4283 +            mAppsView.scrollToTop();                                                                              
4284 +        }                                                                                                         
4285 +        if (updatePredictedApps) {                                                                                
4286 +            tryAndUpdatePredictedApps();                                                                          
4287 +        }                                                                                                         
4288 +        showAppsOrWidgets(animated, State.APPS);                                                                  
4289 +    }                                                                                                             
4290 +                                                                                                                  
4291 +    /**                                                                                                           
4292 +     * Shows the widgets view.                                                                                    
4293 +     */                                                                                                           
4294 +    void showWidgetsView(boolean animated, boolean resetPageToZero) {                                             
4295 +        if (LOGD) Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);              
4296 +        if (resetPageToZero) {                                                                                    
4297 +            mWidgetsView.scrollToTop();                                                                           
4298 +        }                                                                                                         
4299 +        showAppsOrWidgets(animated, State.WIDGETS);                                                               
4300 +                                                                                                                  
4301 +        mWidgetsView.post(new Runnable() {                                                                        
4302 +            @Override                                                                                             
4303 +            public void run() {                                                                                   
4304 +                mWidgetsView.requestFocus();                                                                      
4305 +            }                                                                                                     
4306 +        });                                                                                                       
4307 +    }                                                                                                             
4308 +                                                                                                                  
4309 +    /**                                                                                                           
4310 +     * Sets up the transition to show the apps/widgets view.                                                      
4311 +     *                                                                                                            
4312 +     * @return whether the current from and to state allowed this operation                                       
4313 +     */                                                                                                           
4314 +    // TODO: calling method should use the return value so that when {@code false} is returned                    
4315 +    // the workspace transition doesn't fall into invalid state.                                                  
4316 +    private boolean showAppsOrWidgets(boolean animated, State toState) {                                          
4317 +        if (mState != State.WORKSPACE &&  mState != State.APPS_SPRING_LOADED &&                                   
4318 +                mState != State.WIDGETS_SPRING_LOADED) {                                                          
4319 +            return false;                                                                                         
4320 +        }                                                                                                         
4321 +        if (toState != State.APPS && toState != State.WIDGETS) {                                                  
4322 +            return false;                                                                                         
4323 +        }                                                                                                         
4324 +                                                                                                                  
4325 +        if (toState == State.APPS) {                                                                              
4326 +            mStateTransitionAnimation.startAnimationToAllApps(animated);                                          
4327 +            if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {                    
4328 +                mLauncherCallbacks.onAllAppsShown();                                                              
4329 +            }                                                                                                     
4330 +        } else {                                                                                                  
4331 +            mStateTransitionAnimation.startAnimationToWidgets(animated);                                          
4332 +        }                                                                                                         
4333 +                                                                                                                  
4334 +        // Change the state *after* we've called all the transition code                                          
4335 +        mState = toState;                                                                                         
4336 +                                                                                                                  
4337 +        // Pause the auto-advance of widgets until we are out of AllApps                                          
4338 +        mUserPresent = false;                                                                                     
4339 +        updateAutoAdvanceState();                                                                                 
4340 +        closeFolder();                                                                                            
4341                                                                                                                    
4342          // Send an accessibility event to announce the context change                                             
4343          getWindow().getDecorView()                                                                                
4344                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4345 -                                                                                                                  
4346 -        onWorkspaceShown(animated);                                                                               
4347 -    }                                                                                                             
4348 -                                                                                                                  
4349 -    void showOverviewMode(boolean animated) {                                                                     
4350 -        mWorkspace.setVisibility(View.VISIBLE);                                                                   
4351 -        hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
4352 -        mState = State.WORKSPACE;                                                                                 
4353 -        onWorkspaceShown(animated);                                                                               
4354 -    }                                                                                                             
4355 -                                                                                                                  
4356 -    public void onWorkspaceShown(boolean animated) {                                                              
4357 -    }                                                                                                             
4358 -                                                                                                                  
4359 -    void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
4360 -                     boolean resetPageToZero) {                                                                   
4361 -        if (mState != State.WORKSPACE) return;                                                                    
4362 -                                                                                                                  
4363 -        if (resetPageToZero) {                                                                                    
4364 -            mAppsCustomizeTabHost.reset();                                                                        
4365 -        }                                                                                                         
4366 -        showAppsCustomizeHelper(animated, false, contentType);                                                    
4367 -        mAppsCustomizeTabHost.post(new Runnable() {                                                               
4368 -            @Override                                                                                             
4369 -            public void run() {                                                                                   
4370 -                // We post this in-case the all apps view isn't yet constructed.                                  
4371 -                mAppsCustomizeTabHost.requestFocus();                                                             
4372 -            }                                                                                                     
4373 -        });                                                                                                       
4374 -                                                                                                                  
4375 -        // Change the state *after* we've called all the transition code                                          
4376 -        mState = State.APPS_CUSTOMIZE;                                                                            
4377 -                                                                                                                  
4378 -        // Pause the auto-advance of widgets until we are out of AllApps                                          
4379 -        mUserPresent = false;                                                                                     
4380 -        updateRunning();                                                                                          
4381 -        closeFolder();                                                                                            
4382 -                                                                                                                  
4383 -        // Send an accessibility event to announce the context change                                             
4384 -        getWindow().getDecorView()                                                                                
4385 -                .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4386 -    }                                                                                                             
4387 -                                                                                                                  
4388 -    void enterSpringLoadedDragMode() {                                                                            
4389 -        if (isAllAppsVisible()) {                                                                                 
4390 -            hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
4391 -            mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
4392 -        }                                                                                                         
4393 -    }                                                                                                             
4394 -                                                                                                                  
4395 -    void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
4396 +        return true;                                                                                              
4397 +    }                                                                                                             
4398 +                                                                                                                  
4399 +    /**                                                                                                           
4400 +     * Updates the workspace and interaction state on state change, and return the animation to this              
4401 +     * new state.                                                                                                 
4402 +     */                                                                                                           
4403 +    public Animator startWorkspaceStateChangeAnimation(Workspace.State toState, int toPage,                       
4404 +            boolean animated, HashMap<View, Integer> layerViews) {                                                
4405 +        Workspace.State fromState = mWorkspace.getState();                                                        
4406 +        Animator anim = mWorkspace.setStateWithAnimation(toState, toPage, animated, layerViews);                  
4407 +        updateInteraction(fromState, toState);                                                                    
4408 +        return anim;                                                                                              
4409 +    }                                                                                                             
4410 +                                                                                                                  
4411 +    public void enterSpringLoadedDragMode() {                                                                     
4412 +        if (LOGD) Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", mState.name()));               
4413 +        if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                                    
4414 +                mState == State.WIDGETS_SPRING_LOADED) {                                                          
4415 +            return;                                                                                               
4416 +        }                                                                                                         
4417 +                                                                                                                  
4418 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,                
4419 +                WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true /* animated */,                    
4420 +                null /* onCompleteRunnable */);                                                                   
4421 +        mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;                    
4422 +    }                                                                                                             
4423 +                                                                                                                  
4424 +    public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                          
4425              final Runnable onCompleteRunnable) {                                                                  
4426 -        if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
4427 +        if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;                  
4428 +                                                                                                                  
4429 +        if (successfulDrop) {                                                                                     
4430 +            // We need to trigger all apps hidden to notify search to update itself before the                    
4431 +            // delayed call to showWorkspace below                                                                
4432 +            if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {                    
4433 +                mLauncherCallbacks.onAllAppsHidden();                                                             
4434 +            }                                                                                                     
4435 +        }                                                                                                         
4436                                                                                                                    
4437          mHandler.postDelayed(new Runnable() {                                                                     
4438              @Override                                                                                             
4439              public void run() {                                                                                   
4440                  if (successfulDrop) {                                                                             
4441 +                    // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.                     
4442 +                    //                                                                                            
4443                      // Before we show workspace, hide all apps again because                                      
4444                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
4445                      // clean up our state transition functions                                                    
4446 -                    mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
4447 +                    mWidgetsView.setVisibility(View.GONE);                                                        
4448                      showWorkspace(true, onCompleteRunnable);                                                      
4449                  } else {                                                                                          
4450                      exitSpringLoadedDragMode();                                                                   
4451                  }                                                                                                 
4452              }                                                                                                     
4453          }, delay);                                                                                                
4454      }                                                                                                             
4455                                                                                                                    
4456      void exitSpringLoadedDragMode() {                                                                             
4457 -        if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
4458 -            final boolean animated = true;                                                                        
4459 -            final boolean springLoaded = true;                                                                    
4460 -            showAppsCustomizeHelper(animated, springLoaded);                                                      
4461 -            mState = State.APPS_CUSTOMIZE;                                                                        
4462 -        }                                                                                                         
4463 -        // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
4464 +        if (mState == State.APPS_SPRING_LOADED) {                                                                 
4465 +            showAppsView(true /* animated */, false /* resetListToTop */,                                         
4466 +                    false /* updatePredictedApps */);                                                             
4467 +        } else if (mState == State.WIDGETS_SPRING_LOADED) {                                                       
4468 +            showWidgetsView(true, false);                                                                         
4469 +        }                                                                                                         
4470 +    }                                                                                                             
4471 +                                                                                                                  
4472 +    /**                                                                                                           
4473 +     * Updates the set of predicted apps if it hasn't been updated since the last time Launcher was               
4474 +     * resumed.                                                                                                   
4475 +     */                                                                                                           
4476 +    private void tryAndUpdatePredictedApps() {                                                                    
4477 +        if (mLauncherCallbacks != null) {                                                                         
4478 +            List<ComponentName> apps = mLauncherCallbacks.getPredictedApps();                                     
4479 +            if (!apps.isEmpty()) {                                                                                
4480 +                mAppsView.setPredictedApps(apps);                                                                 
4481 +            }                                                                                                     
4482 +        }                                                                                                         
4483      }                                                                                                             
4484                                                                                                                    
4485      void lockAllApps() {                                                                                          
4486          // TODO                                                                                                   
4487      }                                                                                                             
4488                                                                                                                    
4489      void unlockAllApps() {                                                                                        
4490          // TODO                                                                                                   
4491      }                                                                                                             
4492                                                                                                                    
4493      protected void disableVoiceButtonProxy(boolean disable) {                                                     
4494          // NO-OP                                                                                                  
4495      }                                                                                                             
4496                                                                                                                    
4497 -    public View getQsbBar() {                                                                                     
4498 +    public View getOrCreateQsbBar() {                                                                             
4499          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
4500              return mLauncherCallbacks.getQsbBar();                                                                
4501          }                                                                                                         
4502                                                                                                                    
4503          if (mQsb == null) {                                                                                       
4504              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
4505              if (searchProvider == null) {                                                                         
4506                  return null;                                                                                      
4507              }                                                                                                     
4508                                                                                                                    
4509              Bundle opts = new Bundle();                                                                           
4510              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
4511                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
4512                                                                                                                    
4513              SharedPreferences sp = getSharedPreferences(                                                          
4514                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
4515              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
4516              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
4517              if (!searchProvider.provider.flattenToString().equals(                                                
4518                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
4519                      || (widgetInfo == null)                                                                       
4520                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
4521                  // A valid widget is not already bound.                                                           
4522                  if (widgetId > -1) {                                                                              
4523                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4524                      widgetId = -1;                                                                                
4525                  }                                                                                                 
4526                                                                                                                    
4527                  // Try to bind a new widget                                                                       
4528                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
4529                                                                                                                    
4530                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
4531                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
4532                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4533                      widgetId = -1;                                                                                
4534                  }                                                                                                 
4535                                                                                                                    
4536                  sp.edit()                                                                                         
4537                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
4538                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
4539                      .commit();                                                                                    
4540              }                                                                                                     
4541                                                                                                                    
4542              if (widgetId != -1) {                                                                                 
4543                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
4544                  mQsb.updateAppWidgetOptions(opts);                                                                
4545                  mQsb.setPadding(0, 0, 0, 0);                                                                      
4546                  mSearchDropTargetBar.addView(mQsb);                                                               
4547 +                mSearchDropTargetBar.setQsbSearchBar(mQsb);                                                       
4548              }                                                                                                     
4549          }                                                                                                         
4550          return mQsb;                                                                                              
4551 +    }                                                                                                             
4552 +                                                                                                                  
4553 +    private void reinflateQSBIfNecessary() {                                                                      
4554 +        if (mQsb instanceof LauncherAppWidgetHostView &&                                                          
4555 +                ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                                       
4556 +            mSearchDropTargetBar.removeView(mQsb);                                                                
4557 +            mQsb = null;                                                                                          
4558 +            mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                            
4559 +        }                                                                                                         
4560      }                                                                                                             
4561                                                                                                                    
4562      @Override                                                                                                     
4563      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4564          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4565          final List<CharSequence> text = event.getText();                                                          
4566          text.clear();                                                                                             
4567          // Populate event with a fake title based on the current state.                                           
4568 -        if (mState == State.APPS_CUSTOMIZE) {                                                                     
4569 -            text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4570 +        if (mState == State.APPS) {                                                                               
4571 +            text.add(getString(R.string.all_apps_button_label));                                                  
4572 +        } else if (mState == State.WIDGETS) {                                                                     
4573 +            text.add(getString(R.string.widget_button_text));                                                     
4574          } else {                                                                                                  
4575              text.add(getString(R.string.all_apps_home_button_label));                                             
4576          }                                                                                                         
4577          return result;                                                                                            
4578      }                                                                                                             
4579                                                                                                                    
4580      /**                                                                                                           
4581       * Receives notifications when system dialogs are to be closed.                                               
4582       */                                                                                                           
4583 -    private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4584 +    @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                     
4585          @Override                                                                                                 
4586          public void onReceive(Context context, Intent intent) {                                                   
4587              closeSystemDialogs();                                                                                 
4588          }                                                                                                         
4589      }                                                                                                             
4590                                                                                                                    
4591      /**                                                                                                           
4592       * Receives notifications whenever the appwidgets are reset.                                                  
4593       */                                                                                                           
4594      private class AppWidgetResetObserver extends ContentObserver {                                                
4595          public AppWidgetResetObserver() {                                                                         
4596              super(new Handler());                                                                                 
4597          }                                                                                                         
4598                                                                                                                    
4599          @Override                                                                                                 
4600          public void onChange(boolean selfChange) {                                                                
4601              onAppWidgetReset();                                                                                   
4602          }                                                                                                         
4603      }                                                                                                             
4604                                                                                                                    
4605      /**                                                                                                           
4606       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4607       * in onResume.                                                                                               
4608       *                                                                                                            
4609       * This needs to be called from incoming places where resources might have been loaded                        
4610 -     * while we are paused.  That is becaues the Configuration might be wrong                                     
4611 -     * when we're not running, and if it comes back to what it was when we                                        
4612 -     * were paused, we are not restarted.                                                                         
4613 +     * while the activity is paused. That is because the Configuration (e.g., rotation)  might be                 
4614 +     * wrong when we're not running, and if the activity comes back to what the configuration was                 
4615 +     * when we were paused, activity is not restarted.                                                            
4616       *                                                                                                            
4617       * Implementation of the method from LauncherModel.Callbacks.                                                 
4618       *                                                                                                            
4619 -     * @return true if we are currently paused.  The caller might be able to                                      
4620 -     * skip some work in that case since we will come back again.                                                 
4621 +     * @return {@code true} if we are currently paused. The caller might be able to skip some work                
4622       */                                                                                                           
4623      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4624          if (mPaused) {                                                                                            
4625 -            Log.i(TAG, "Deferring update until onResume");                                                        
4626 +            if (LOGD) Log.d(TAG, "Deferring update until onResume");                                              
4627              if (deletePreviousRunnables) {                                                                        
4628                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4629                  }                                                                                                 
4630              }                                                                                                     
4631              mBindOnResumeCallbacks.add(run);                                                                      
4632              return true;                                                                                          
4633          } else {                                                                                                  
4634              return false;                                                                                         
4635          }                                                                                                         
4636      }                                                                                                             
4637                                                                                                                    
4638      private boolean waitUntilResume(Runnable run) {                                                               
4639          return waitUntilResume(run, false);                                                                       
4640      }                                                                                                             
4641                                                                                                                    
4642      public void addOnResumeCallback(Runnable run) {                                                               
4643          mOnResumeCallbacks.add(run);                                                                              
4644      }                                                                                                             
4645                                                                                                                    
4646      /**                                                                                                           
4647       * If the activity is currently paused, signal that we need to re-run the loader                              
4648       * in onResume.                                                                                               
4649       *                                                                                                            
4650       * This needs to be called from incoming places where resources might have been loaded                        
4651       * while we are paused.  That is becaues the Configuration might be wrong                                     
4652       * when we're not running, and if it comes back to what it was when we                                        
4653       * were paused, we are not restarted.                                                                         
4654       *                                                                                                            
4655       * Implementation of the method from LauncherModel.Callbacks.                                                 
4656       *                                                                                                            
4657       * @return true if we are currently paused.  The caller might be able to                                      
4658       * skip some work in that case since we will come back again.                                                 
4659       */                                                                                                           
4660      public boolean setLoadOnResume() {                                                                            
4661          if (mPaused) {                                                                                            
4662 -            Log.i(TAG, "setLoadOnResume");                                                                        
4663 +            if (LOGD) Log.d(TAG, "setLoadOnResume");                                                              
4664              mOnResumeNeedsLoad = true;                                                                            
4665              return true;                                                                                          
4666          } else {                                                                                                  
4667              return false;                                                                                         
4668          }                                                                                                         
4669      }                                                                                                             
4670                                                                                                                    
4671      /**                                                                                                           
4672       * Implementation of the method from LauncherModel.Callbacks.                                                 
4673       */                                                                                                           
4674      public int getCurrentWorkspaceScreen() {                                                                      
4675          if (mWorkspace != null) {                                                                                 
4676              return mWorkspace.getCurrentPage();                                                                   
4677          } else {                                                                                                  
4678              return SCREEN_COUNT / 2;                                                                              
4679          }                                                                                                         
4680      }                                                                                                             
4681                                                                                                                    
4682      /**                                                                                                           
4683       * Refreshes the shortcuts shown on the workspace.                                                            
4684       *                                                                                                            
4685       * Implementation of the method from LauncherModel.Callbacks.                                                 
4686       */                                                                                                           
4687      public void startBinding() {                                                                                  
4688          setWorkspaceLoading(true);                                                                                
4689                                                                                                                    
4690          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4691          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4692          // from scratch again                                                                                     
4693          mBindOnResumeCallbacks.clear();                                                                           
4694                                                                                                                    
4695          // Clear the workspace because it's going to be rebound                                                   
4696          mWorkspace.clearDropTargets();                                                                            
4697          mWorkspace.removeAllWorkspaceScreens();                                                                   
4698                                                                                                                    
4699          mWidgetsToAdvance.clear();                                                                                
4700          if (mHotseat != null) {                                                                                   
4701              mHotseat.resetLayout();                                                                               
4702          }                                                                                                         
4703      }                                                                                                             
4704                                                                                                                    
4705      @Override                                                                                                     
4706      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4707          bindAddScreens(orderedScreenIds);                                                                         
4708                                                                                                                    
4709          // If there are no screens, we need to have an empty screen                                               
4710          if (orderedScreenIds.size() == 0) {                                                                       
4711              mWorkspace.addExtraEmptyScreen();                                                                     
4712          }                                                                                                         
4713                                                                                                                    
4714          // Create the custom content page (this call updates mDefaultScreen which calls                           
4715          // setCurrentPage() so ensure that all pages are added before calling this).                              
4716          if (hasCustomContentToLeft()) {                                                                           
4717              mWorkspace.createCustomContentContainer();                                                            
4718              populateCustomContentContainer();                                                                     
4719          }                                                                                                         
4720      }                                                                                                             
4721                                                                                                                    
4722      @Override                                                                                                     
4723      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4724          // Log to disk                                                                                            
4725          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4726          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4727                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4728          int count = orderedScreenIds.size();                                                                      
4729          for (int i = 0; i < count; i++) {                                                                         
4730              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4731          }                                                                                                         
4732      }                                                                                                             
4733                                                                                                                    
4734 -    @Override                                                                                                     
4735 -    public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4736 -            final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4737 -        showWorkspace(true, new Runnable() {                                                                      
4738 -                                                                                                                  
4739 -            @Override                                                                                             
4740 -            public void run() {                                                                                   
4741 -                mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4742 -                addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4743 -            }                                                                                                     
4744 -        });                                                                                                       
4745 -    }                                                                                                             
4746 -                                                                                                                  
4747      private boolean shouldShowWeightWatcher() {                                                                   
4748          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4749          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4750          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4751                                                                                                                    
4752          return show;                                                                                              
4753      }                                                                                                             
4754                                                                                                                    
4755      private void toggleShowWeightWatcher() {                                                                      
4756          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4757          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4758          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4759                                                                                                                    
4760          show = !show;                                                                                             
4761                                                                                                                    
4762          SharedPreferences.Editor editor = sp.edit();                                                              
4763          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4764          editor.commit();                                                                                          
4765                                                                                                                    
4766          if (mWeightWatcher != null) {                                                                             
4767              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4768          }                                                                                                         
4769      }                                                                                                             
4770                                                                                                                    
4771      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4772                                final ArrayList<ItemInfo> addNotAnimated,                                           
4773                                final ArrayList<ItemInfo> addAnimated,                                              
4774                                final ArrayList<AppInfo> addedApps) {                                               
4775          Runnable r = new Runnable() {                                                                             
4776              public void run() {                                                                                   
4777                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4778              }                                                                                                     
4779          };                                                                                                        
4780          if (waitUntilResume(r)) {                                                                                 
4781              return;                                                                                               
4782          }                                                                                                         
4783                                                                                                                    
4784          // Add the new screens                                                                                    
4785          if (newScreens != null) {                                                                                 
4786              bindAddScreens(newScreens);                                                                           
4787          }                                                                                                         
4788                                                                                                                    
4789          // We add the items without animation on non-visible pages, and with                                      
4790          // animations on the new page (which we will try and snap to).                                            
4791          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4792              bindItems(addNotAnimated, 0,                                                                          
4793                      addNotAnimated.size(), false);                                                                
4794          }                                                                                                         
4795          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4796              bindItems(addAnimated, 0,                                                                             
4797                      addAnimated.size(), true);                                                                    
4798          }                                                                                                         
4799                                                                                                                    
4800          // Remove the extra empty screen                                                                          
4801          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4802                                                                                                                    
4803 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
4804 -                addedApps != null && mAppsCustomizeContent != null) {                                             
4805 -            mAppsCustomizeContent.addApps(addedApps);                                                             
4806 +        if (addedApps != null && mAppsView != null) {                                                             
4807 +            mAppsView.addApps(addedApps);                                                                         
4808          }                                                                                                         
4809      }                                                                                                             
4810                                                                                                                    
4811      /**                                                                                                           
4812       * Bind the items start-end from the list.                                                                    
4813       *                                                                                                            
4814       * Implementation of the method from LauncherModel.Callbacks.                                                 
4815       */                                                                                                           
4816      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4817                            final boolean forceAnimateIcons) {                                                      
4818          Runnable r = new Runnable() {                                                                             
4819              public void run() {                                                                                   
4820                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4821              }                                                                                                     
4822          };                                                                                                        
4823          if (waitUntilResume(r)) {                                                                                 
4824              return;                                                                                               
4825          }                                                                                                         
4826                                                                                                                    
4827          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4828          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4829          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4830          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4831          Workspace workspace = mWorkspace;                                                                         
4832          long newShortcutsScreenId = -1;                                                                           
4833          for (int i = start; i < end; i++) {                                                                       
4834              final ItemInfo item = shortcuts.get(i);                                                               
4835                                                                                                                    
4836              // Short circuit if we are loading dock items for a configuration which has no dock                   
4837              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4838                      mHotseat == null) {                                                                           
4839                  continue;                                                                                         
4840              }                                                                                                     
4841                                                                                                                    
4842              switch (item.itemType) {                                                                              
4843                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4844                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4845                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4846                      View shortcut = createShortcut(info);                                                         
4847                                                                                                                    
4848                      /*                                                                                            
4849                       * TODO: FIX collision case                                                                   
4850                       */                                                                                           
4851                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4852                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4853                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4854                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4855                              Object tag = v.getTag();                                                              
4856                              String desc = "Collision while binding workspace item: " + item                       
4857                                      + ". Collides with " + tag;                                                   
4858                              if (LauncherAppState.isDogfoodBuild()) {                                              
4859                                  throw (new RuntimeException(desc));                                               
4860                              } else {                                                                              
4861                                  Log.d(TAG, desc);                                                                 
4862                              }                                                                                     
4863                          }                                                                                         
4864                      }                                                                                             
4865                                                                                                                    
4866                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4867                              item.cellY, 1, 1);                                                                    
4868                      if (animateIcons) {                                                                           
4869                          // Animate all the applications up now                                                    
4870                          shortcut.setAlpha(0f);                                                                    
4871                          shortcut.setScaleX(0f);                                                                   
4872                          shortcut.setScaleY(0f);                                                                   
4873                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4874                          newShortcutsScreenId = item.screenId;                                                     
4875                      }                                                                                             
4876                      break;                                                                                        
4877                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4878                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4879                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4880                              (FolderInfo) item, mIconCache);                                                       
4881                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4882                              item.cellY, 1, 1);                                                                    
4883                      break;                                                                                        
4884                  default:                                                                                          
4885                      throw new RuntimeException("Invalid Item Type");                                              
4886              }                                                                                                     
4887          }                                                                                                         
4888                                                                                                                    
4889          if (animateIcons) {                                                                                       
4890              // Animate to the correct page                                                                        
4891              if (newShortcutsScreenId > -1) {                                                                      
4892                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4893                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4894                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4895                      public void run() {                                                                           
4896                          anim.playTogether(bounceAnims);                                                           
4897                          anim.start();                                                                             
4898                      }                                                                                             
4899                  };                                                                                                
4900                  if (newShortcutsScreenId != currentScreenId) {                                                    
4901                      // We post the animation slightly delayed to prevent slowdowns                                
4902                      // when we are loading right after we return to launcher.                                     
4903                      mWorkspace.postDelayed(new Runnable() {                                                       
4904                          public void run() {                                                                       
4905                              if (mWorkspace != null) {                                                             
4906                                  mWorkspace.snapToPage(newScreenIndex);                                            
4907                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4908                                          NEW_APPS_ANIMATION_DELAY);                                                
4909                              }                                                                                     
4910                          }                                                                                         
4911                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4912                  } else {                                                                                          
4913                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4914                  }                                                                                                 
4915              }                                                                                                     
4916          }                                                                                                         
4917          workspace.requestLayout();                                                                                
4918      }                                                                                                             
4919                                                                                                                    
4920      /**                                                                                                           
4921       * Implementation of the method from LauncherModel.Callbacks.                                                 
4922       */                                                                                                           
4923 -    public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4924 +    public void bindFolders(final LongArrayMap<FolderInfo> folders) {                                             
4925          Runnable r = new Runnable() {                                                                             
4926              public void run() {                                                                                   
4927                  bindFolders(folders);                                                                             
4928              }                                                                                                     
4929          };                                                                                                        
4930          if (waitUntilResume(r)) {                                                                                 
4931              return;                                                                                               
4932          }                                                                                                         
4933 -        sFolders.clear();                                                                                         
4934 -        sFolders.putAll(folders);                                                                                 
4935 +        sFolders = folders.clone();                                                                               
4936      }                                                                                                             
4937                                                                                                                    
4938      /**                                                                                                           
4939       * Add the views for a widget to the workspace.                                                               
4940       *                                                                                                            
4941       * Implementation of the method from LauncherModel.Callbacks.                                                 
4942       */                                                                                                           
4943      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4944          Runnable r = new Runnable() {                                                                             
4945              public void run() {                                                                                   
4946                  bindAppWidget(item);                                                                              
4947              }                                                                                                     
4948          };                                                                                                        
4949          if (waitUntilResume(r)) {                                                                                 
4950              return;                                                                                               
4951          }                                                                                                         
4952                                                                                                                    
4953          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4954          if (DEBUG_WIDGETS) {                                                                                      
4955              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4956          }                                                                                                         
4957          final Workspace workspace = mWorkspace;                                                                   
4958                                                                                                                    
4959          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4960                  LauncherModel.getProviderInfo(this, item.providerName, item.user);                                
4961                                                                                                                    
4962          if (!mIsSafeModeEnabled                                                                                   
4963                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4964                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4965              if (appWidgetInfo == null) {                                                                          
4966                  if (DEBUG_WIDGETS) {                                                                              
4967                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4968                              + " belongs to component " + item.providerName                                        
4969                              + ", as the povider is null");                                                        
4970                  }                                                                                                 
4971                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4972                  return;                                                                                           
4973              }                                                                                                     
4974              // Note: This assumes that the id remap broadcast is received before this step.                       
4975              // If that is not the case, the id remap will be ignored and user may see the                         
4976              // click to setup view.                                                                               
4977 -            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     
4978 +            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);               
4979              pendingInfo.spanX = item.spanX;                                                                       
4980              pendingInfo.spanY = item.spanY;                                                                       
4981              pendingInfo.minSpanX = item.minSpanX;                                                                 
4982              pendingInfo.minSpanY = item.minSpanY;                                                                 
4983 -            Bundle options =                                                                                      
4984 -                    AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4985 +            Bundle options = null;                                                                                
4986 +                    WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);                           
4987                                                                                                                    
4988              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4989              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4990                      newWidgetId, appWidgetInfo, options);                                                         
4991                                                                                                                    
4992              // TODO consider showing a permission dialog when the widget is clicked.                              
4993              if (!success) {                                                                                       
4994                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4995                  if (DEBUG_WIDGETS) {                                                                              
4996                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4997                              + " belongs to component " + item.providerName                                        
4998                              + ", as the launcher is unable to bing a new widget id");                             
4999                  }                                                                                                 
5000                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
5001                  return;                                                                                           
5002              }                                                                                                     
5003                                                                                                                    
5004              item.appWidgetId = newWidgetId;                                                                       
5005                                                                                                                    
5006              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
5007              // the widget is ready to go.                                                                         
5008              item.restoreStatus = (appWidgetInfo.configure == null)                                                
5009                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
5010                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
5011                                                                                                                    
5012              LauncherModel.updateItemInDatabase(this, item);                                                       
5013          }                                                                                                         
5014                                                                                                                    
5015          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
5016              final int appWidgetId = item.appWidgetId;                                                             
5017              if (DEBUG_WIDGETS) {                                                                                  
5018                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
5019                          + appWidgetInfo.provider);                                                                
5020              }                                                                                                     
5021                                                                                                                    
5022              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
5023          } else {                                                                                                  
5024              appWidgetInfo = null;                                                                                 
5025              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
5026                      mIsSafeModeEnabled);                                                                          
5027              view.updateIcon(mIconCache);                                                                          
5028              item.hostView = view;                                                                                 
5029              item.hostView.updateAppWidget(null);                                                                  
5030              item.hostView.setOnClickListener(this);                                                               
5031          }                                                                                                         
5032                                                                                                                    
5033          item.hostView.setTag(item);                                                                               
5034          item.onBindAppWidget(this);                                                                               
5035                                                                                                                    
5036          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
5037                  item.cellY, item.spanX, item.spanY, false);                                                       
5038          if (!item.isCustomWidget()) {                                                                             
5039              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
5040          }                                                                                                         
5041                                                                                                                    
5042          workspace.requestLayout();                                                                                
5043                                                                                                                    
5044          if (DEBUG_WIDGETS) {                                                                                      
5045              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
5046                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
5047          }                                                                                                         
5048      }                                                                                                             
5049                                                                                                                    
5050      /**                                                                                                           
5051       * Restores a pending widget.                                                                                 
5052       *                                                                                                            
5053       * @param appWidgetId The app widget id                                                                       
5054       * @param cellInfo The position on screen where to create the widget.                                         
5055       */                                                                                                           
5056      private void completeRestoreAppWidget(final int appWidgetId) {                                                
5057          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
5058          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
5059              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
5060              return;                                                                                               
5061          }                                                                                                         
5062                                                                                                                    
5063          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
5064          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
5065                                                                                                                    
5066          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
5067          LauncherModel.updateItemInDatabase(this, info);                                                           
5068      }                                                                                                             
5069                                                                                                                    
5070      public void onPageBoundSynchronously(int page) {                                                              
5071          mSynchronouslyBoundPages.add(page);                                                                       
5072      }                                                                                                             
5073                                                                                                                    
5074      /**                                                                                                           
5075       * Callback saying that there aren't any more items to bind.                                                  
5076       *                                                                                                            
5077       * Implementation of the method from LauncherModel.Callbacks.                                                 
5078       */                                                                                                           
5079 -    public void finishBindingItems(final boolean upgradePath) {                                                   
5080 +    public void finishBindingItems() {                                                                            
5081          Runnable r = new Runnable() {                                                                             
5082              public void run() {                                                                                   
5083 -                finishBindingItems(upgradePath);                                                                  
5084 +                finishBindingItems();                                                                             
5085              }                                                                                                     
5086          };                                                                                                        
5087          if (waitUntilResume(r)) {                                                                                 
5088              return;                                                                                               
5089          }                                                                                                         
5090          if (mSavedState != null) {                                                                                
5091              if (!mWorkspace.hasFocus()) {                                                                         
5092                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
5093              }                                                                                                     
5094              mSavedState = null;                                                                                   
5095          }                                                                                                         
5096                                                                                                                    
5097          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
5098                                                                                                                    
5099          setWorkspaceLoading(false);                                                                               
5100          sendLoadingCompleteBroadcastIfNecessary();                                                                
5101                                                                                                                    
5102          // If we received the result of any pending adds while the loader was running (e.g. the                   
5103          // widget configuration forced an orientation change), process them now.                                  
5104          if (sPendingAddItem != null) {                                                                            
5105              final long screenId = completeAdd(sPendingAddItem);                                                   
5106                                                                                                                    
5107              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
5108              // the screen would be guaranteed to exist after bind, and the page would be set through              
5109              // the workspace restore process.                                                                     
5110              mWorkspace.post(new Runnable() {                                                                      
5111                  @Override                                                                                         
5112                  public void run() {                                                                               
5113                      mWorkspace.snapToScreenId(screenId);                                                          
5114                  }                                                                                                 
5115              });                                                                                                   
5116              sPendingAddItem = null;                                                                               
5117          }                                                                                                         
5118                                                                                                                    
5119 -        if (upgradePath) {                                                                                        
5120 -            mWorkspace.getUniqueComponents(true, null);                                                           
5121 -            mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
5122 -        }                                                                                                         
5123 -        PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
5124 +        InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
5125                                                                                                                    
5126          if (mLauncherCallbacks != null) {                                                                         
5127 -            mLauncherCallbacks.finishBindingItems(upgradePath);                                                   
5128 +            mLauncherCallbacks.finishBindingItems(false);                                                         
5129          }                                                                                                         
5130      }                                                                                                             
5131                                                                                                                    
5132      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
5133          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
5134              String permission =                                                                                   
5135                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
5136              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
5137              sendBroadcast(intent, permission);                                                                    
5138              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
5139              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
5140              editor.apply();                                                                                       
5141          }                                                                                                         
5142      }                                                                                                             
5143                                                                                                                    
5144      public boolean isAllAppsButtonRank(int rank) {                                                                
5145          if (mHotseat != null) {                                                                                   
5146              return mHotseat.isAllAppsButtonRank(rank);                                                            
5147          }                                                                                                         
5148          return false;                                                                                             
5149      }                                                                                                             
5150                                                                                                                    
5151      private boolean canRunNewAppsAnimation() {                                                                    
5152          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
5153          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
5154      }                                                                                                             
5155                                                                                                                    
5156      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
5157          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
5158                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
5159                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
5160                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
5161          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
5162          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
5163          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
5164          return bounceAnim;                                                                                        
5165      }                                                                                                             
5166                                                                                                                    
5167      public boolean useVerticalBarLayout() {                                                                       
5168 -        return LauncherAppState.getInstance().getDynamicGrid().                                                   
5169 -                getDeviceProfile().isVerticalBarLayout();                                                         
5170 +        return mDeviceProfile.isVerticalBarLayout();                                                              
5171      }                                                                                                             
5172                                                                                                                    
5173      protected Rect getSearchBarBounds() {                                                                         
5174 -        return LauncherAppState.getInstance().getDynamicGrid().                                                   
5175 -                getDeviceProfile().getSearchBarBounds();                                                          
5176 +        return mDeviceProfile.getSearchBarBounds(Utilities.isRtl(getResources()));                                
5177      }                                                                                                             
5178                                                                                                                    
5179      public void bindSearchablesChanged() {                                                                        
5180          if (mSearchDropTargetBar == null) {                                                                       
5181              return;                                                                                               
5182          }                                                                                                         
5183          if (mQsb != null) {                                                                                       
5184              mSearchDropTargetBar.removeView(mQsb);                                                                
5185              mQsb = null;                                                                                          
5186          }                                                                                                         
5187 -        mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        
5188 -    }                                                                                                             
5189 +        mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                                
5190 +    }                                                                                                             
5191 +                                                                                                                  
5192 +    /**                                                                                                           
5193 +     * A runnable that we can dequeue and re-enqueue when all applications are bound (to prevent                  
5194 +     * multiple calls to bind the same list.)                                                                     
5195 +     */                                                                                                           
5196 +    @Thunk ArrayList<AppInfo> mTmpAppsList;                                                                       
5197 +    private Runnable mBindAllApplicationsRunnable = new Runnable() {                                              
5198 +        public void run() {                                                                                       
5199 +            bindAllApplications(mTmpAppsList);                                                                    
5200 +            mTmpAppsList = null;                                                                                  
5201 +        }                                                                                                         
5202 +    };                                                                                                            
5203                                                                                                                    
5204      /**                                                                                                           
5205       * Add the icons for all apps.                                                                                
5206       *                                                                                                            
5207       * Implementation of the method from LauncherModel.Callbacks.                                                 
5208       */                                                                                                           
5209      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
5210 -        if (LauncherAppState.isDisableAllApps()) {                                                                
5211 -            if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
5212 -                if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
5213 -                    getHotseat().addAllAppsFolder(mIconCache, apps,                                               
5214 -                            mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
5215 -                }                                                                                                 
5216 -                mIntentsOnWorkspaceFromUpgradePath = null;                                                        
5217 -            }                                                                                                     
5218 -            if (mAppsCustomizeContent != null) {                                                                  
5219 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
5220 -                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
5221 -            }                                                                                                     
5222 -        } else {                                                                                                  
5223 -            if (mAppsCustomizeContent != null) {                                                                  
5224 -                mAppsCustomizeContent.setApps(apps);                                                              
5225 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
5226 -                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
5227 -            }                                                                                                     
5228 +        if (waitUntilResume(mBindAllApplicationsRunnable, true)) {                                                
5229 +            mTmpAppsList = apps;                                                                                  
5230 +            return;                                                                                               
5231 +        }                                                                                                         
5232 +                                                                                                                  
5233 +        if (mAppsView != null) {                                                                                  
5234 +            mAppsView.setApps(apps);                                                                              
5235          }                                                                                                         
5236          if (mLauncherCallbacks != null) {                                                                         
5237              mLauncherCallbacks.bindAllApplications(apps);                                                         
5238          }                                                                                                         
5239      }                                                                                                             
5240                                                                                                                    
5241      /**                                                                                                           
5242       * A package was updated.                                                                                     
5243       *                                                                                                            
5244       * Implementation of the method from LauncherModel.Callbacks.                                                 
5245       */                                                                                                           
5246      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
5247          Runnable r = new Runnable() {                                                                             
5248              public void run() {                                                                                   
5249                  bindAppsUpdated(apps);                                                                            
5250              }                                                                                                     
5251          };                                                                                                        
5252          if (waitUntilResume(r)) {                                                                                 
5253              return;                                                                                               
5254          }                                                                                                         
5255                                                                                                                    
5256 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
5257 -                mAppsCustomizeContent != null) {                                                                  
5258 -            mAppsCustomizeContent.updateApps(apps);                                                               
5259 +        if (mAppsView != null) {                                                                                  
5260 +            mAppsView.updateApps(apps);                                                                           
5261          }                                                                                                         
5262      }                                                                                                             
5263                                                                                                                    
5264      @Override                                                                                                     
5265      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
5266          Runnable r = new Runnable() {                                                                             
5267              public void run() {                                                                                   
5268                  bindWidgetsRestored(widgets);                                                                     
5269              }                                                                                                     
5270          };                                                                                                        
5271          if (waitUntilResume(r)) {                                                                                 
5272              return;                                                                                               
5273          }                                                                                                         
5274          mWorkspace.widgetsRestored(widgets);                                                                      
5275      }                                                                                                             
5276                                                                                                                    
5277      /**                                                                                                           
5278       * Some shortcuts were updated in the background.                                                             
5279       *                                                                                                            
5280       * Implementation of the method from LauncherModel.Callbacks.                                                 
5281       */                                                                                                           
5282      @Override                                                                                                     
5283      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
5284              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
5285          Runnable r = new Runnable() {                                                                             
5286              public void run() {                                                                                   
5287                  bindShortcutsChanged(updated, removed, user);                                                     
5288              }                                                                                                     
5289          };                                                                                                        
5290          if (waitUntilResume(r)) {                                                                                 
5291              return;                                                                                               
5292          }                                                                                                         
5293                                                                                                                    
5294          if (!updated.isEmpty()) {                                                                                 
5295              mWorkspace.updateShortcuts(updated);                                                                  
5296          }                                                                                                         
5297                                                                                                                    
5298          if (!removed.isEmpty()) {                                                                                 
5299              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
5300              for (ShortcutInfo si : removed) {                                                                     
5301                  removedComponents.add(si.getTargetComponent());                                                   
5302              }                                                                                                     
5303              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
5304              // Notify the drag controller                                                                         
5305              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
5306          }                                                                                                         
5307      }                                                                                                             
5308                                                                                                                    
5309      /**                                                                                                           
5310       * Update the state of a package, typically related to install state.                                         
5311       *                                                                                                            
5312       * Implementation of the method from LauncherModel.Callbacks.                                                 
5313       */                                                                                                           
5314      @Override                                                                                                     
5315 -    public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
5316 -        if (mWorkspace != null) {                                                                                 
5317 -            mWorkspace.updatePackageState(installInfo);                                                           
5318 -        }                                                                                                         
5319 -    }                                                                                                             
5320 -                                                                                                                  
5321 -    /**                                                                                                           
5322 -     * Update the label and icon of all the icons in a package                                                    
5323 -     *                                                                                                            
5324 -     * Implementation of the method from LauncherModel.Callbacks.                                                 
5325 -     */                                                                                                           
5326 -    @Override                                                                                                     
5327 -    public void updatePackageBadge(String packageName) {                                                          
5328 -        if (mWorkspace != null) {                                                                                 
5329 -            mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
5330 -        }                                                                                                         
5331 +    public void bindRestoreItemsChange(final HashSet<ItemInfo> updates) {                                         
5332 +        Runnable r = new Runnable() {                                                                             
5333 +            public void run() {                                                                                   
5334 +                bindRestoreItemsChange(updates);                                                                  
5335 +            }                                                                                                     
5336 +        };                                                                                                        
5337 +        if (waitUntilResume(r)) {                                                                                 
5338 +            return;                                                                                               
5339 +        }                                                                                                         
5340 +                                                                                                                  
5341 +        mWorkspace.updateRestoreItems(updates);                                                                   
5342      }                                                                                                             
5343                                                                                                                    
5344      /**                                                                                                           
5345       * A package was uninstalled.  We take both the super set of packageNames                                     
5346       * in addition to specific applications to remove, the reason being that                                      
5347       * this can be called when a package is updated as well.  In that scenario,                                   
5348       * we only remove specific components from the workspace, where as                                            
5349       * package-removal should clear all items by package name.                                                    
5350       *                                                                                                            
5351       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
5352       * Implementation of the method from LauncherModel.Callbacks.                                                 
5353       */                                                                                                           
5354      @Override                                                                                                     
5355      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
5356              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
5357          Runnable r = new Runnable() {                                                                             
5358              public void run() {                                                                                   
5359                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
5360              }                                                                                                     
5361          };                                                                                                        
5362          if (waitUntilResume(r)) {                                                                                 
5363              return;                                                                                               
5364          }                                                                                                         
5365                                                                                                                    
5366          if (reason == 0) {                                                                                        
5367              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
5368              for (AppInfo info : appInfos) {                                                                       
5369                  removedComponents.add(info.componentName);                                                        
5370              }                                                                                                     
5371              if (!packageNames.isEmpty()) {                                                                        
5372                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
5373              }                                                                                                     
5374              if (!removedComponents.isEmpty()) {                                                                   
5375                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
5376              }                                                                                                     
5377              // Notify the drag controller                                                                         
5378              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
5379                                                                                                                    
5380          } else {                                                                                                  
5381              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
5382          }                                                                                                         
5383                                                                                                                    
5384          // Update AllApps                                                                                         
5385 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
5386 -                mAppsCustomizeContent != null) {                                                                  
5387 -            mAppsCustomizeContent.removeApps(appInfos);                                                           
5388 -        }                                                                                                         
5389 -    }                                                                                                             
5390 -                                                                                                                  
5391 -    /**                                                                                                           
5392 -     * A number of packages were updated.                                                                         
5393 -     */                                                                                                           
5394 -    private ArrayList<Object> mWidgetsAndShortcuts;                                                               
5395 +        if (mAppsView != null) {                                                                                  
5396 +            mAppsView.removeApps(appInfos);                                                                       
5397 +        }                                                                                                         
5398 +    }                                                                                                             
5399 +                                                                                                                  
5400      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
5401              public void run() {                                                                                   
5402 -                bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
5403 -                mWidgetsAndShortcuts = null;                                                                      
5404 +                bindAllPackages(mWidgetsModel);                                                                   
5405              }                                                                                                     
5406          };                                                                                                        
5407 -    public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
5408 +                                                                                                                  
5409 +    @Override                                                                                                     
5410 +    public void bindAllPackages(final WidgetsModel model) {                                                       
5411          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
5412 -            mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
5413 +            mWidgetsModel = model;                                                                                
5414              return;                                                                                               
5415          }                                                                                                         
5416                                                                                                                    
5417 -        // Update the widgets pane                                                                                
5418 -        if (mAppsCustomizeContent != null) {                                                                      
5419 -            mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
5420 +        if (mWidgetsView != null && model != null) {                                                              
5421 +            mWidgetsView.addWidgets(model);                                                                       
5422 +            mWidgetsModel = null;                                                                                 
5423          }                                                                                                         
5424      }                                                                                                             
5425                                                                                                                    
5426      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
5427          final Display d = getWindowManager().getDefaultDisplay();                                                 
5428          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
5429          switch (d.getRotation()) {                                                                                
5430          case Surface.ROTATION_0:                                                                                  
5431          case Surface.ROTATION_180:                                                                                
5432              // We are currently in the same basic orientation as the natural orientation                          
5433              naturalOri = configOri;                                                                               
5434              break;                                                                                                
5435          case Surface.ROTATION_90:                                                                                 
5436          case Surface.ROTATION_270:                                                                                
5437              // We are currently in the other basic orientation to the natural orientation                         
5438              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
5439                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
5440              break;                                                                                                
5441          }                                                                                                         
5442                                                                                                                    
5443          int[] oriMap = {                                                                                          
5444                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
5445                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
5446                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
5447                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
5448          };                                                                                                        
5449          // Since the map starts at portrait, we need to offset if this device's natural orientation               
5450          // is landscape.                                                                                          
5451          int indexOffset = 0;                                                                                      
5452          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
5453              indexOffset = 1;                                                                                      
5454          }                                                                                                         
5455          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
5456      }                                                                                                             
5457                                                                                                                    
5458      public void lockScreenOrientation() {                                                                         
5459          if (Utilities.isRotationEnabled(this)) {                                                                  
5460              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
5461                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
5462                          .getConfiguration().orientation));                                                        
5463              } else {                                                                                              
5464                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
5465              }                                                                                                     
5466          }                                                                                                         
5467      }                                                                                                             
5468      public void unlockScreenOrientation(boolean immediate) {                                                      
5469          if (Utilities.isRotationEnabled(this)) {                                                                  
5470              if (immediate) {                                                                                      
5471                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
5472              } else {                                                                                              
5473                  mHandler.postDelayed(new Runnable() {                                                             
5474                      public void run() {                                                                           
5475                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
5476                      }                                                                                             
5477                  }, mRestoreScreenOrientationDelay);                                                               
5478              }                                                                                                     
5479          }                                                                                                         
5480      }                                                                                                             
5481                                                                                                                    
5482      protected boolean isLauncherPreinstalled() {                                                                  
5483          if (mLauncherCallbacks != null) {                                                                         
5484              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
5485          }                                                                                                         
5486          PackageManager pm = getPackageManager();                                                                  
5487          try {                                                                                                     
5488              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
5489              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
5490                  return true;                                                                                      
5491              } else {                                                                                              
5492                  return false;                                                                                     
5493              }                                                                                                     
5494          } catch (NameNotFoundException e) {                                                                       
5495              e.printStackTrace();                                                                                  
5496              return false;                                                                                         
5497          }                                                                                                         
5498      }                                                                                                             
5499                                                                                                                    
5500      /**                                                                                                           
5501       * This method indicates whether or not we should suggest default wallpaper dimensions                        
5502       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
5503       */                                                                                                           
5504      protected boolean overrideWallpaperDimensions() {                                                             
5505          if (mLauncherCallbacks != null) {                                                                         
5506              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
5507          }                                                                                                         
5508          return true;                                                                                              
5509      }                                                                                                             
5510                                                                                                                    
5511      /**                                                                                                           
5512       * To be overridden by subclasses to indicate that there is an activity to launch                             
5513       * before showing the standard launcher experience.                                                           
5514       */                                                                                                           
5515      protected boolean hasFirstRunActivity() {                                                                     
5516          if (mLauncherCallbacks != null) {                                                                         
5517              return mLauncherCallbacks.hasFirstRunActivity();                                                      
5518          }                                                                                                         
5519          return false;                                                                                             
5520      }                                                                                                             
5521                                                                                                                    
5522      /**                                                                                                           
5523       * To be overridden by subclasses to launch any first run activity                                            
5524       */                                                                                                           
5525      protected Intent getFirstRunActivity() {                                                                      
5526          if (mLauncherCallbacks != null) {                                                                         
5527              return mLauncherCallbacks.getFirstRunActivity();                                                      
5528          }                                                                                                         
5529          return null;                                                                                              
5530 +    }                                                                                                             
5531 +                                                                                                                  
5532 +    /**                                                                                                           
5533 +     * Returns whether the launcher callbacks overrides search in all apps.                                       
5534 +     */                                                                                                           
5535 +    @Thunk boolean isAllAppsSearchOverridden() {                                                                  
5536 +        if (DISABLE_ALL_APPS_SEARCH_INTEGRATION) {                                                                
5537 +            return false;                                                                                         
5538 +        }                                                                                                         
5539 +                                                                                                                  
5540 +        if (mLauncherCallbacks != null) {                                                                         
5541 +            return mLauncherCallbacks.overrideAllAppsSearch();                                                    
5542 +        }                                                                                                         
5543 +        return false;                                                                                             
5544      }                                                                                                             
5545                                                                                                                    
5546      private boolean shouldRunFirstRunActivity() {                                                                 
5547          return !ActivityManager.isRunningInTestHarness() &&                                                       
5548                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
5549      }                                                                                                             
5550                                                                                                                    
5551      protected boolean hasRunFirstRunActivity() {                                                                  
5552          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
5553      }                                                                                                             
5554                                                                                                                    
5555      public boolean showFirstRunActivity() {                                                                       
5556          if (shouldRunFirstRunActivity() &&                                                                        
5557                  hasFirstRunActivity()) {                                                                          
5558              Intent firstRunIntent = getFirstRunActivity();                                                        
5559              if (firstRunIntent != null) {                                                                         
5560                  startActivity(firstRunIntent);                                                                    
5561                  markFirstRunActivityShown();                                                                      
5562                  return true;                                                                                      
5563              }                                                                                                     
5564          }                                                                                                         
5565          return false;                                                                                             
5566      }                                                                                                             
5567                                                                                                                    
5568      private void markFirstRunActivityShown() {                                                                    
5569          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5570          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
5571          editor.apply();                                                                                           
5572      }                                                                                                             
5573                                                                                                                    
5574      /**                                                                                                           
5575       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
5576       * screen that must be displayed and dismissed.                                                               
5577       */                                                                                                           
5578      protected boolean hasDismissableIntroScreen() {                                                               
5579          if (mLauncherCallbacks != null) {                                                                         
5580              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
5581          }                                                                                                         
5582          return false;                                                                                             
5583      }                                                                                                             
5584                                                                                                                    
5585      /**                                                                                                           
5586       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
5587       */                                                                                                           
5588      protected View getIntroScreen() {                                                                             
5589          if (mLauncherCallbacks != null) {                                                                         
5590              return mLauncherCallbacks.getIntroScreen();                                                           
5591          }                                                                                                         
5592          return null;                                                                                              
5593      }                                                                                                             
5594                                                                                                                    
5595      /**                                                                                                           
5596       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
5597       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
5598       */                                                                                                           
5599      private boolean shouldShowIntroScreen() {                                                                     
5600          return hasDismissableIntroScreen() &&                                                                     
5601                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5602      }                                                                                                             
5603                                                                                                                    
5604      protected void showIntroScreen() {                                                                            
5605          View introScreen = getIntroScreen();                                                                      
5606          changeWallpaperVisiblity(false);                                                                          
5607          if (introScreen != null) {                                                                                
5608              mDragLayer.showOverlayView(introScreen);                                                              
5609          }                                                                                                         
5610          if (mLauncherOverlayContainer != null) {                                                                  
5611              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
5612          }                                                                                                         
5613      }                                                                                                             
5614                                                                                                                    
5615      public void dismissIntroScreen() {                                                                            
5616          markIntroScreenDismissed();                                                                               
5617          if (showFirstRunActivity()) {                                                                             
5618              // We delay hiding the intro view until the first run activity is showing. This                       
5619              // avoids a blip.                                                                                     
5620              mWorkspace.postDelayed(new Runnable() {                                                               
5621                  @Override                                                                                         
5622                  public void run() {                                                                               
5623                      mDragLayer.dismissOverlayView();                                                              
5624                      if (mLauncherOverlayContainer != null) {                                                      
5625                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
5626                      }                                                                                             
5627                      showFirstRunClings();                                                                         
5628                  }                                                                                                 
5629              }, ACTIVITY_START_DELAY);                                                                             
5630          } else {                                                                                                  
5631              mDragLayer.dismissOverlayView();                                                                      
5632              if (mLauncherOverlayContainer != null) {                                                              
5633                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
5634              }                                                                                                     
5635              showFirstRunClings();                                                                                 
5636          }                                                                                                         
5637          changeWallpaperVisiblity(true);                                                                           
5638      }                                                                                                             
5639                                                                                                                    
5640      private void markIntroScreenDismissed() {                                                                     
5641          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5642          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5643          editor.apply();                                                                                           
5644      }                                                                                                             
5645                                                                                                                    
5646 -    private void showFirstRunClings() {                                                                           
5647 +    @Thunk void showFirstRunClings() {                                                                            
5648          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5649          // on the device, then we always show the first run cling experience (or if there is no                   
5650          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5651          LauncherClings launcherClings = new LauncherClings(this);                                                 
5652          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5653              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5654                  launcherClings.showMigrationCling();                                                              
5655              } else {                                                                                              
5656                  launcherClings.showLongPressCling(true);                                                          
5657              }                                                                                                     
5658          }                                                                                                         
5659      }                                                                                                             
5660                                                                                                                    
5661      void showWorkspaceSearchAndHotseat() {                                                                        
5662          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5663          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5664          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5665          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5666      }                                                                                                             
5667                                                                                                                    
5668      void hideWorkspaceSearchAndHotseat() {                                                                        
5669          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5670          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5671          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5672          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5673      }                                                                                                             
5674                                                                                                                    
5675      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5676          // Called from search suggestion, not supported in other profiles.                                        
5677          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5678          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5679          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5680                  myUser);                                                                                          
5681          if (activityInfo == null) {                                                                               
5682              return null;                                                                                          
5683          }                                                                                                         
5684 -        return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5685 +        return new AppInfo(this, activityInfo, myUser, mIconCache);                                               
5686      }                                                                                                             
5687                                                                                                                    
5688      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5689              Bitmap icon) {                                                                                        
5690          // Called from search suggestion, not supported in other profiles.                                        
5691          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5692                  UserHandleCompat.myUserHandle());                                                                 
5693      }                                                                                                             
5694                                                                                                                    
5695      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5696              Bitmap icon, UserHandleCompat user) {                                                                 
5697          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5698          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5699          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5700      }                                                                                                             
5701                                                                                                                    
5702      protected void moveWorkspaceToDefaultScreen() {                                                               
5703          mWorkspace.moveToDefaultScreen(false);                                                                    
5704      }                                                                                                             
5705                                                                                                                    
5706      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5707          dragView.setTag(dragInfo);                                                                                
5708          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5709          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5710      }                                                                                                             
5711                                                                                                                    
5712      @Override                                                                                                     
5713      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5714          if (mLauncherCallbacks != null) {                                                                         
5715              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5716          }                                                                                                         
5717      }                                                                                                             
5718                                                                                                                    
5719      /**                                                                                                           
5720       * Prints out out state for debugging.                                                                        
5721       */                                                                                                           
5722      public void dumpState() {                                                                                     
5723          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5724          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5725          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5726          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5727          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5728          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5729          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5730          mModel.dumpState();                                                                                       
5731 -                                                                                                                  
5732 -        if (mAppsCustomizeContent != null) {                                                                      
5733 -            mAppsCustomizeContent.dumpState();                                                                    
5734 -        }                                                                                                         
5735 +        // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                          
5736 +                                                                                                                  
5737          Log.d(TAG, "END launcher3 dump state");                                                                   
5738      }                                                                                                             
5739                                                                                                                    
5740      @Override                                                                                                     
5741      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5742          super.dump(prefix, fd, writer, args);                                                                     
5743          synchronized (sDumpLogs) {                                                                                
5744              writer.println(" ");                                                                                  
5745              writer.println("Debug logs: ");                                                                       
5746              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5747                  writer.println("  " + sDumpLogs.get(i));                                                          
5748              }                                                                                                     
5749          }                                                                                                         
5750          if (mLauncherCallbacks != null) {                                                                         
5751              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5752          }                                                                                                         
5753      }                                                                                                             
5754                                                                                                                    
5755      public static void dumpDebugLogsToConsole() {                                                                 
5756          if (DEBUG_DUMP_LOG) {                                                                                     
5757              synchronized (sDumpLogs) {                                                                            
5758                  Log.d(TAG, "");                                                                                   
5759                  Log.d(TAG, "*********************");                                                              
5760                  Log.d(TAG, "Launcher debug logs: ");                                                              
5761                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5762                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5763                  }                                                                                                 
5764                  Log.d(TAG, "*********************");                                                              
5765                  Log.d(TAG, "");                                                                                   
5766              }                                                                                                     
5767          }                                                                                                         
5768      }                                                                                                             
5769                                                                                                                    
5770      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5771          addDumpLog(tag, log, null, debugLog);                                                                     
5772      }                                                                                                             
5773                                                                                                                    
5774      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5775          if (debugLog) {                                                                                           
5776              if (e != null) {                                                                                      
5777                  Log.d(tag, log, e);                                                                               
5778              } else {                                                                                              
5779                  Log.d(tag, log);                                                                                  
5780              }                                                                                                     
5781          }                                                                                                         
5782          if (DEBUG_DUMP_LOG) {                                                                                     
5783              sDateStamp.setTime(System.currentTimeMillis());                                                       
5784              synchronized (sDumpLogs) {                                                                            
5785                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5786                      + (e == null ? "" : (", Exception: " + e)));                                                  
5787              }                                                                                                     
5788          }                                                                                                         
5789      }                                                                                                             
5790                                                                                                                    
5791      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5792          return sCustomAppWidgets.get(name);                                                                       
5793      }                                                                                                             
5794                                                                                                                    
5795      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5796          return sCustomAppWidgets;                                                                                 
5797      }                                                                                                             
5798                                                                                                                    
5799      public void dumpLogsToLocalData() {                                                                           
5800          if (DEBUG_DUMP_LOG) {                                                                                     
5801              new AsyncTask<Void, Void, Void>() {                                                                   
5802                  public Void doInBackground(Void ... args) {                                                       
5803                      boolean success = false;                                                                      
5804                      sDateStamp.setTime(sRunStart);                                                                
5805                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5806                              + sDateStamp.getDay() + "_"                                                           
5807                              + sDateStamp.getHours() + "-"                                                         
5808                              + sDateStamp.getMinutes() + "_"                                                       
5809                              + sDateStamp.getSeconds() + ".txt";                                                   
5810                                                                                                                    
5811                      FileOutputStream fos = null;                                                                  
5812                      File outFile = null;                                                                          
5813                      try {                                                                                         
5814                          outFile = new File(getFilesDir(), FILENAME);                                              
5815                          outFile.createNewFile();                                                                  
5816                          fos = new FileOutputStream(outFile);                                                      
5817                      } catch (Exception e) {                                                                       
5818                          e.printStackTrace();                                                                      
5819                      }                                                                                             
5820                      if (fos != null) {                                                                            
5821                          PrintWriter writer = new PrintWriter(fos);                                                
5822                                                                                                                    
5823                          writer.println(" ");                                                                      
5824                          writer.println("Debug logs: ");                                                           
5825                          synchronized (sDumpLogs) {                                                                
5826                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5827                                  writer.println("  " + sDumpLogs.get(i));                                          
5828                              }                                                                                     
5829                          }                                                                                         
5830                          writer.close();                                                                           
5831                      }                                                                                             
5832                      try {                                                                                         
5833                          if (fos != null) {                                                                        
5834                              fos.close();                                                                          
5835                              success = true;                                                                       
5836                          }                                                                                         
5837                      } catch (IOException e) {                                                                     
5838                          e.printStackTrace();                                                                      
5839                      }                                                                                             
5840                      return null;                                                                                  
5841                  }                                                                                                 
5842              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5843          }                                                                                                         
5844      }                                                                                                             
5845  }                                                                                                                 
5846                                                                                                                    
5847 -interface LauncherTransitionable {                                                                                
5848 -    View getContent();                                                                                            
5849 -    void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5850 -    void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5851 -    void onLauncherTransitionStep(Launcher l, float t);                                                           
5852 -    void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5853 -}                                                                                                                 
5854 -                                                                                                                  
5855  interface DebugIntents {                                                                                          
5856      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5857      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5858  }                                                                                                                 
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25  import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           

  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.IntentSender;                                                                              
  46  import android.content.SharedPreferences;                                                                         
  47  import android.content.pm.ActivityInfo;                                                                           
  48  import android.content.pm.ApplicationInfo;                                                                        
  49  import android.content.pm.PackageManager;                                                                         
  50  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  51  import android.content.res.Configuration;                                                                         
  52  import android.content.res.Resources;                                                                             
  53  import android.database.ContentObserver;                                                                          
  54  import android.database.sqlite.SQLiteDatabase;                                                                    
  55  import android.graphics.Bitmap;                                                                                   
  56  import android.graphics.Canvas;                                                                                   
  57  import android.graphics.Color;                                                                                    
  58  import android.graphics.PorterDuff;                                                                               
  59  import android.graphics.Rect;                                                                                     

  60  import android.graphics.drawable.Drawable;                                                                        
  61  import android.net.Uri;                                                                                           
  62  import android.os.AsyncTask;                                                                                      
  63  import android.os.Build;                                                                                          
  64  import android.os.Bundle;                                                                                         
  65  import android.os.Environment;                                                                                    
  66  import android.os.Handler;                                                                                        
  67  import android.os.Message;                                                                                        
  68  import android.os.StrictMode;                                                                                     
  69  import android.os.SystemClock;                                                                                    
  70  import android.text.Selection;                                                                                    
  71  import android.text.SpannableStringBuilder;                                                                       
  72  import android.text.TextUtils;                                                                                    
  73  import android.text.method.TextKeyListener;                                                                       
  74  import android.util.Log;                                                                                          
  75  import android.view.Display;                                                                                      
  76  import android.view.Gravity;                                                                                      
  77  import android.view.HapticFeedbackConstants;                                                                      
  78  import android.view.KeyEvent;                                                                                     
  79  import android.view.LayoutInflater;                                                                               
  80  import android.view.Menu;                                                                                         
  81  import android.view.MotionEvent;                                                                                  
  82  import android.view.Surface;                                                                                      
  83  import android.view.View;                                                                                         
  84  import android.view.View.OnClickListener;                                                                         
  85  import android.view.View.OnLongClickListener;                                                                     
  86  import android.view.ViewAnimationUtils;                                                                           
  87  import android.view.ViewGroup;                                                                                    
  88  import android.view.ViewStub;                                                                                     
  89  import android.view.ViewTreeObserver;                                                                             
  90  import android.view.Window;                                                                                       
  91  import android.view.WindowManager;                                                                                
  92  import android.view.accessibility.AccessibilityEvent;                                                             
  93  import android.view.animation.AccelerateInterpolator;                                                             
  94  import android.view.animation.DecelerateInterpolator;                                                             
  95  import android.view.inputmethod.InputMethodManager;                                                               
  96  import android.widget.Advanceable;                                                                                
  97  import android.widget.FrameLayout;                                                                                
  98  import android.widget.ImageView;                                                                                  

  99  import android.widget.Toast;                                                                                      
 100                                                                                                                    
 101  import com.android.launcher3.DropTarget.DragObject;                                                               
 102  import com.android.launcher3.PagedView.PageSwitchListener;                                                        


 103  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 104  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 105  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 106  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 107  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 108  import com.android.launcher3.compat.UserHandleCompat;                                                             
 109  import com.android.launcher3.compat.UserManagerCompat;                                                            






 110                                                                                                                    
 111  import java.io.DataInputStream;                                                                                   
 112  import java.io.DataOutputStream;                                                                                  
 113  import java.io.File;                                                                                              
 114  import java.io.FileDescriptor;                                                                                    
 115  import java.io.FileNotFoundException;                                                                             
 116  import java.io.FileOutputStream;                                                                                  
 117  import java.io.IOException;                                                                                       
 118  import java.io.PrintWriter;                                                                                       
 119  import java.lang.reflect.Field;                                                                                   
 120  import java.lang.reflect.InvocationTargetException;                                                               
 121  import java.lang.reflect.Method;                                                                                  
 122  import java.text.DateFormat;                                                                                      
 123  import java.util.ArrayList;                                                                                       
 124  import java.util.Collection;                                                                                      
 125  import java.util.Date;                                                                                            
 126  import java.util.HashMap;                                                                                         
 127  import java.util.HashSet;                                                                                         
 128  import java.util.List;                                                                                            
 129  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 130                                                                                                                    
 131  /**                                                                                                               
 132   * Default launcher application.                                                                                  
 133   */                                                                                                               
 134  public class Launcher extends Activity                                                                            
 135          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 136                     View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     


 137      static final String TAG = "Launcher";                                                                         
 138      static final boolean LOGD = false;                                                                            
 139                                                                                                                    



 140      static final boolean PROFILE_STARTUP = false;                                                                 
 141      static final boolean DEBUG_WIDGETS = false;                                                                   

 142      static final boolean DEBUG_STRICT_MODE = false;                                                               
 143      static final boolean DEBUG_RESUME_TIME = false;                                                               
 144      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 145                                                                                                                    
 146      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 147                                                                                                                    
 148      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 149      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 150      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 151      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 152      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 153                                                                                                                    
 154      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 155      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  




 156                                                                                                                    
 157      /**                                                                                                           
 158       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 159       * request codes used internally.                                                                             
 160       */                                                                                                           
 161      protected static final int REQUEST_LAST = 100;                                                                
 162                                                                                                                    
 163      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 164                                                                                                                    
 165      static final int SCREEN_COUNT = 5;                                                                            
 166                                                                                                                    
 167      // To turn on these properties, type                                                                          
 168      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 169      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 170      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 171                                                                                                                    
 172      // The Intent extra that defines whether to ignore the launch animation                                       
 173      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 174              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 175                                                                                                                    
 176      // Type: int                                                                                                  
 177      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 178      // Type: int                                                                                                  
 179      private static final String RUNTIME_STATE = "launcher.state";                                                 
 180      // Type: int                                                                                                  
 181      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 182      // Type: int                                                                                                  
 183      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 188      // Type: boolean                                                                                              
 189      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 190      // Type: long                                                                                                 
 191      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 192      // Type: int                                                                                                  
 193      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 194      // Type: int                                                                                                  
 195      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 196      // Type: parcelable                                                                                           
 197      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 198      // Type: parcelable                                                                                           
 199      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 200      // Type: int[]                                                                                                
 201      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 202                                                                                                                    
 203      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 204      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 205                                                                                                                    
 206      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 207      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 208              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 209                                                                                                                    
 210      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 211      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 212                                                                                                                    
 213      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 214      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 215                                                                                                                    
 216      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 217                                                                                                                    
 218      /** The different states that Launcher can be in. */                                                          
 219      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 220      private State mState = State.WORKSPACE;                                                                       
 221      private AnimatorSet mStateAnimation;                                                                          



 222                                                                                                                    
 223      private boolean mIsSafeModeEnabled;                                                                           
 224                                                                                                                    
 225      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 226      LauncherOverlay mLauncherOverlay;                                                                             
 227      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 228                                                                                                                    
 229      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 230      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 231      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 232      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 233                                                                                                                    
 234      private static final Object sLock = new Object();                                                             
 235                                                                                                                    
 236      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 237      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 238                                                                                                                    
 239      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 240      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 241      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 242      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 243      private static final int SINGLE_FRAME_DELAY = 16;                                                             

 244                                                                                                                    
 245      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 246              = new CloseSystemDialogsIntentReceiver();                                                             
 247      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 248                                                                                                                    
 249      private LayoutInflater mInflater;                                                                             
 250                                                                                                                    
 251      private Workspace mWorkspace;                                                                                 

 252      private View mLauncherView;                                                                                   
 253      private View mPageIndicators;                                                                                 
 254      private DragLayer mDragLayer;                                                                                 

 255      private DragController mDragController;                                                                       
 256      private View mWeightWatcher;                                                                                  
 257                                                                                                                    
 258      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 259      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 260                                                                                                                    
 261      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            

 262      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 263      private int mPendingAddWidgetId = -1;                                                                         
 264                                                                                                                    
 265      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 266                                                                                                                    
 267      private FolderInfo mFolderInfo;                                                                               
 268                                                                                                                    
 269      private Hotseat mHotseat;                                                                                     
 270      private ViewGroup mOverviewPanel;                                                                             
 271                                                                                                                    
 272      private View mAllAppsButton;                                                                                  
 273                                                                                                                    
 274      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 275      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 276      private AppsCustomizePagedView mAppsCustomizeContent;                                                         








 277      private boolean mAutoAdvanceRunning = false;                                                                  
 278      private AppWidgetHostView mQsb;                                                                               
 279                                                                                                                    
 280      private Bundle mSavedState;                                                                                   
 281      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 282      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 283      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 284      private State mOnResumeState = State.NONE;                                                                    
 285                                                                                                                    
 286      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 287                                                                                                                    
 288      private boolean mWorkspaceLoading = true;                                                                     

 289                                                                                                                    
 290      private boolean mPaused = true;                                                                               
 291      private boolean mRestoring;                                                                                   
 292      private boolean mWaitingForResult;                                                                            
 293      private boolean mOnResumeNeedsLoad;                                                                           
 294                                                                                                                    
 295      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 296      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 297                                                                                                                    
 298      private Bundle mSavedInstanceState;                                                                           
 299                                                                                                                    
 300      private LauncherModel mModel;                                                                                 
 301      private IconCache mIconCache;                                                                                 
 302      private boolean mUserPresent = true;                                                                          

 303      private boolean mVisible = false;                                                                             
 304      private boolean mHasFocus = false;                                                                            
 305      private boolean mAttached = false;                                                                            
 306                                                                                                                    
 307      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 308                                                                                                                    
 309      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          



 310                                                                                                                    
 311      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 312                                                                                                                    
 313      public static final int BUILD_LAYER = 0;                                                                      
 314      public static final int BUILD_AND_SET_LAYER = 1;                                                              
 315                                                                                                                    
 316      // Related to the auto-advancing of widgets                                                                   
 317      private final int ADVANCE_MSG = 1;                                                                            
 318      private final int mAdvanceInterval = 20000;                                                                   
 319      private final int mAdvanceStagger = 250;                                                                      
 320      private long mAutoAdvanceSentTime;                                                                            
 321      private long mAutoAdvanceTimeLeft = -1;                                                                       
 322      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              

 323          new HashMap<View, AppWidgetProviderInfo>();                                                               
 324                                                                                                                    
 325      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 326      // match the sensor state.                                                                                    
 327      private final int mRestoreScreenOrientationDelay = 500;                                                       
 328                                                                                                                    
 329      private Drawable mWorkspaceBackgroundDrawable;                                                                

 330                                                                                                                    
 331      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 332      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 333                                                                                                                    
 334      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 335      static Date sDateStamp = new Date();                                                                          
 336      static DateFormat sDateFormat =                                                                               
 337              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 338      static long sRunStart = System.currentTimeMillis();                                                           
 339      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 340                                                                                                                    
 341      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 342      // it from the context.                                                                                       
 343      private SharedPreferences mSharedPrefs;                                                                       
 344                                                                                                                    
 345      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 346                                                                                                                    
 347      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 348      // when we scroll to that page on resume.                                                                     
 349      private ImageView mFolderIconImageView;                                                                       

 350      private Bitmap mFolderIconBitmap;                                                                             
 351      private Canvas mFolderIconCanvas;                                                                             
 352      private Rect mRectForFolderAnimation = new Rect();                                                            
 353                                                                                                                    





 354      private BubbleTextView mWaitingForResume;                                                                     
 355                                                                                                                    
 356      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 357              new HashMap<String, CustomAppWidget>();                                                               
 358                                                                                                                    
 359      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 360      static {                                                                                                      
 361          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 362              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                
 363          }                                                                                                         
 364      }                                                                                                             
 365                                                                                                                    
 366      private Runnable mBuildLayersRunnable = new Runnable() {                                                      













 367          public void run() {                                                                                       
 368              if (mWorkspace != null) {                                                                             
 369                  mWorkspace.buildPageHardwareLayers();                                                             
 370              }                                                                                                     
 371          }                                                                                                         
 372      };                                                                                                            
 373                                                                                                                    
 374      private static PendingAddArguments sPendingAddItem;                                                           
 375                                                                                                                    
 376      private static class PendingAddArguments {                                                                    

 377          int requestCode;                                                                                          
 378          Intent intent;                                                                                            
 379          long container;                                                                                           
 380          long screenId;                                                                                            
 381          int cellX;                                                                                                
 382          int cellY;                                                                                                
 383          int appWidgetId;                                                                                          
 384      }                                                                                                             
 385                                                                                                                    
 386      private Stats mStats;                                                                                         
 387                                                                                                                    
 388      FocusIndicatorView mFocusHandler;                                                                             
 389                                                                                                                    
 390      @Override                                                                                                     
 391      protected void onCreate(Bundle savedInstanceState) {                                                          
 392          if (DEBUG_STRICT_MODE) {                                                                                  
 393              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 394                      .detectDiskReads()                                                                            
 395                      .detectDiskWrites()                                                                           
 396                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 397                      .penaltyLog()                                                                                 
 398                      .build());                                                                                    
 399              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 400                      .detectLeakedSqlLiteObjects()                                                                 
 401                      .detectLeakedClosableObjects()                                                                
 402                      .penaltyLog()                                                                                 
 403                      .penaltyDeath()                                                                               
 404                      .build());                                                                                    
 405          }                                                                                                         
 406                                                                                                                    
 407          if (mLauncherCallbacks != null) {                                                                         
 408              mLauncherCallbacks.preOnCreate();                                                                     
 409          }                                                                                                         
 410                                                                                                                    
 411          super.onCreate(savedInstanceState);                                                                       
 412                                                                                                                    
 413          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 414          LauncherAppState app = LauncherAppState.getInstance();                                                    
 415          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 416                                                                                                                    
 417          // Lazy-initialize the dynamic grid                                                                       
 418          DeviceProfile grid = app.initDynamicGrid(this);                                                           








 419                                                                                                                    
 420          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 421          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 422                  Context.MODE_PRIVATE);                                                                            
 423          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 424          mModel = app.setLauncher(this);                                                                           
 425          mIconCache = app.getIconCache();                                                                          
 426          mIconCache.flushInvalidIcons(grid);                                                                       

 427          mDragController = new DragController(this);                                                               
 428          mInflater = getLayoutInflater();                                                                          

 429                                                                                                                    
 430          mStats = new Stats(this);                                                                                 
 431                                                                                                                    
 432          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 433                                                                                                                    
 434          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 435          mAppWidgetHost.startListening();                                                                          
 436                                                                                                                    
 437          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 438          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 439          // LauncherModel load.                                                                                    
 440          mPaused = false;                                                                                          
 441                                                                                                                    
 442          if (PROFILE_STARTUP) {                                                                                    
 443              android.os.Debug.startMethodTracing(                                                                  
 444                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 445          }                                                                                                         
 446                                                                                                                    
 447          checkForLocaleChange();                                                                                   
 448          setContentView(R.layout.launcher);                                                                        
 449                                                                                                                    
 450          setupViews();                                                                                             
 451          grid.layout(this);                                                                                        

 452                                                                                                                    
 453          registerContentObservers();                                                                               
 454                                                                                                                    
 455          lockAllApps();                                                                                            
 456                                                                                                                    
 457          mSavedState = savedInstanceState;                                                                         
 458          restoreState(mSavedState);                                                                                
 459                                                                                                                    
 460          if (PROFILE_STARTUP) {                                                                                    
 461              android.os.Debug.stopMethodTracing();                                                                 
 462          }                                                                                                         
 463                                                                                                                    
 464          if (!mRestoring) {                                                                                        
 465              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 466                  // If the user leaves launcher, then we should just load items asynchronously when                
 467                  // they return.                                                                                   
 468                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         

 469              } else {                                                                                              
 470                  // We only load the page synchronously if the user rotates (or triggers a                         
 471                  // configuration change) while launcher is in the foreground                                      
 472                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            

 473              }                                                                                                     
 474          }                                                                                                         
 475                                                                                                                    
 476          // For handling default keys                                                                              
 477          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 478          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 479                                                                                                                    
 480          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 481          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 482                                                                                                                    
 483          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 484          unlockScreenOrientation(true);                                                                            
 485                                                                                                                    
 486          if (mLauncherCallbacks != null) {                                                                         
 487              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 488              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 489                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 490                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 491                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 492                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 493                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 494              }                                                                                                     
 495          }                                                                                                         
 496                                                                                                                    
 497          if (shouldShowIntroScreen()) {                                                                            
 498              showIntroScreen();                                                                                    
 499          } else {                                                                                                  
 500              showFirstRunActivity();                                                                               
 501              showFirstRunClings();                                                                                 
 502          }                                                                                                         
 503      }                                                                                                             
 504                                                                                                                    
 505      private LauncherCallbacks mLauncherCallbacks;                                                                 
 506                                                                                                                    
 507      public void onPostCreate(Bundle savedInstanceState) {                                                         
 508          super.onPostCreate(savedInstanceState);                                                                   
 509          if (mLauncherCallbacks != null) {                                                                         
 510              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 511          }                                                                                                         
 512      }                                                                                                             
 513                                                                                                                    
 514      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 515          mLauncherCallbacks = callbacks;                                                                           





















 516          return true;                                                                                              
 517      }                                                                                                             
 518                                                                                                                    
 519      @Override                                                                                                     
 520      public void onLauncherProviderChange() {                                                                      
 521          if (mLauncherCallbacks != null) {                                                                         
 522              mLauncherCallbacks.onLauncherProviderChange();                                                        
 523          }                                                                                                         
 524      }                                                                                                             
 525                                                                                                                    
 526      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 527      protected boolean hasCustomContentToLeft() {                                                                  
 528          if (mLauncherCallbacks != null) {                                                                         
 529              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 530          }                                                                                                         
 531          return false;                                                                                             
 532      }                                                                                                             
 533                                                                                                                    
 534      /**                                                                                                           
 535       * To be overridden by subclasses to populate the custom content container and call                           
 536       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 537       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 538       */                                                                                                           
 539      protected void populateCustomContentContainer() {                                                             
 540          if (mLauncherCallbacks != null) {                                                                         
 541              mLauncherCallbacks.populateCustomContentContainer();                                                  
 542          }                                                                                                         
 543      }                                                                                                             
 544                                                                                                                    
 545      /**                                                                                                           
 546       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 547       * ensure the custom content page is added or removed if necessary.                                           
 548       */                                                                                                           
 549      protected void invalidateHasCustomContentToLeft() {                                                           
 550          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 551              // Not bound yet, wait for bindScreens to be called.                                                  
 552              return;                                                                                               
 553          }                                                                                                         
 554                                                                                                                    
 555          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 556              // Create the custom content page and call the subclass to populate it.                               
 557              mWorkspace.createCustomContentContainer();                                                            
 558              populateCustomContentContainer();                                                                     
 559          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 560              mWorkspace.removeCustomContentPage();                                                                 
 561          }                                                                                                         
 562      }                                                                                                             
 563                                                                                                                    
 564      private void checkForLocaleChange() {                                                                         

 565          if (sLocaleConfiguration == null) {                                                                       
 566              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 567                  @Override                                                                                         
 568                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 569                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 570                      readConfiguration(Launcher.this, localeConfiguration);                                        
 571                      return localeConfiguration;                                                                   
 572                  }                                                                                                 
 573                                                                                                                    
 574                  @Override                                                                                         
 575                  protected void onPostExecute(LocaleConfiguration result) {                                        
 576                      sLocaleConfiguration = result;                                                                
 577                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 578                  }                                                                                                 
 579              }.execute();                                                                                          
 580              return;                                                                                               
 581          }                                                                                                         
 582                                                                                                                    
 583          final Configuration configuration = getResources().getConfiguration();                                    
 584                                                                                                                    
 585          final String previousLocale = sLocaleConfiguration.locale;                                                
 586          final String locale = configuration.locale.toString();                                                    
 587                                                                                                                    
 588          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 589          final int mcc = configuration.mcc;                                                                        
 590                                                                                                                    
 591          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 592          final int mnc = configuration.mnc;                                                                        
 593                                                                                                                    
 594          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 595                                                                                                                    
 596          if (localeChanged) {                                                                                      
 597              sLocaleConfiguration.locale = locale;                                                                 
 598              sLocaleConfiguration.mcc = mcc;                                                                       
 599              sLocaleConfiguration.mnc = mnc;                                                                       
 600                                                                                                                    
 601              mIconCache.flush();                                                                                   
 602                                                                                                                    
 603              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 604              new AsyncTask<Void, Void, Void>() {                                                                   
 605                  public Void doInBackground(Void ... args) {                                                       
 606                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 607                      return null;                                                                                  
 608                  }                                                                                                 
 609              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 610          }                                                                                                         
 611      }                                                                                                             
 612                                                                                                                    
 613      private static class LocaleConfiguration {                                                                    

 614          public String locale;                                                                                     
 615          public int mcc = -1;                                                                                      
 616          public int mnc = -1;                                                                                      
 617      }                                                                                                             
 618                                                                                                                    
 619      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   

 620          DataInputStream in = null;                                                                                
 621          try {                                                                                                     
 622              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 623              configuration.locale = in.readUTF();                                                                  
 624              configuration.mcc = in.readInt();                                                                     
 625              configuration.mnc = in.readInt();                                                                     
 626          } catch (FileNotFoundException e) {                                                                       
 627              // Ignore                                                                                             
 628          } catch (IOException e) {                                                                                 
 629              // Ignore                                                                                             
 630          } finally {                                                                                               
 631              if (in != null) {                                                                                     
 632                  try {                                                                                             
 633                      in.close();                                                                                   
 634                  } catch (IOException e) {                                                                         
 635                      // Ignore                                                                                     
 636                  }                                                                                                 
 637              }                                                                                                     
 638          }                                                                                                         
 639      }                                                                                                             
 640                                                                                                                    
 641      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  

 642          DataOutputStream out = null;                                                                              
 643          try {                                                                                                     
 644              out = new DataOutputStream(context.openFileOutput(                                                    
 645                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 646              out.writeUTF(configuration.locale);                                                                   
 647              out.writeInt(configuration.mcc);                                                                      
 648              out.writeInt(configuration.mnc);                                                                      
 649              out.flush();                                                                                          
 650          } catch (FileNotFoundException e) {                                                                       
 651              // Ignore                                                                                             
 652          } catch (IOException e) {                                                                                 
 653              //noinspection ResultOfMethodCallIgnored                                                              
 654              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 655          } finally {                                                                                               
 656              if (out != null) {                                                                                    
 657                  try {                                                                                             
 658                      out.close();                                                                                  
 659                  } catch (IOException e) {                                                                         
 660                      // Ignore                                                                                     
 661                  }                                                                                                 
 662              }                                                                                                     
 663          }                                                                                                         
 664      }                                                                                                             
 665                                                                                                                    
 666      public Stats getStats() {                                                                                     
 667          return mStats;                                                                                            
 668      }                                                                                                             
 669                                                                                                                    
 670      public LayoutInflater getInflater() {                                                                         
 671          return mInflater;                                                                                         
 672      }                                                                                                             
 673                                                                                                                    
 674      boolean isDraggingEnabled() {                                                                                 

 675          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 676          // that is subsequently removed from the workspace in startBinding().                                     
 677          return !mModel.isLoadingWorkspace();                                                                      
 678      }                                                                                                             
 679                                                                                                                    
 680      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 681      public static int generateViewId() {                                                                          
 682          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 683              return View.generateViewId();                                                                         
 684          } else {                                                                                                  
 685              // View.generateViewId() is not available. The following fallback logic is a copy                     
 686              // of its implementation.                                                                             
 687              for (;;) {                                                                                            
 688                  final int result = sNextGeneratedId.get();                                                        
 689                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 690                  int newValue = result + 1;                                                                        
 691                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 692                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 693                      return result;                                                                                
 694                  }                                                                                                 
 695              }                                                                                                     
 696          }                                                                                                         
 697      }                                                                                                             
 698                                                                                                                    
 699      public int getViewIdForItem(ItemInfo info) {                                                                  
 700          // This cast is safe given the > 2B range for int.                                                        
 701          int itemId = (int) info.id;                                                                               
 702          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 703              return mItemIdToViewId.get(itemId);                                                                   
 704          }                                                                                                         
 705          int viewId = generateViewId();                                                                            
 706          mItemIdToViewId.put(itemId, viewId);                                                                      
 707          return viewId;                                                                                            
 708      }                                                                                                             
 709                                                                                                                    
 710      /**                                                                                                           
 711       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 712       * a configuration step, this allows the proper animations to run after other transitions.                    
 713       */                                                                                                           
 714      private long completeAdd(PendingAddArguments args) {                                                          
 715          long screenId = args.screenId;                                                                            
 716          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 717              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 718              // that the drop page actually exists.                                                                
 719              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 720          }                                                                                                         
 721                                                                                                                    
 722          switch (args.requestCode) {                                                                               
 723              case REQUEST_CREATE_SHORTCUT:                                                                         
 724                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 725                          args.cellY);                                                                              
 726                  break;                                                                                            
 727              case REQUEST_CREATE_APPWIDGET:                                                                        
 728                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 729                  break;                                                                                            
 730              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 731                  completeRestoreAppWidget(args.appWidgetId);                                                       
 732                  break;                                                                                            
 733          }                                                                                                         
 734          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 735          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 736          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 737          resetAddInfo();                                                                                           
 738          return screenId;                                                                                          
 739      }                                                                                                             
 740                                                                                                                    
 741      private void handleActivityResult(                                                                            
 742              final int requestCode, final int resultCode, final Intent data) {                                     
 743          // Reset the startActivity waiting flag                                                                   
 744          setWaitingForResult(false);                                                                               
 745          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 746          mPendingAddWidgetId = -1;                                                                                 
 747                                                                                                                    
 748          Runnable exitSpringLoaded = new Runnable() {                                                              
 749              @Override                                                                                             
 750              public void run() {                                                                                   
 751                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 752                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 753              }                                                                                                     
 754          };                                                                                                        
 755                                                                                                                    
 756          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 757              final int appWidgetId = data != null ?                                                                
 758                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 759              if (resultCode == RESULT_CANCELED) {                                                                  
 760                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 761                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 762                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 763              } else if (resultCode == RESULT_OK) {                                                                 
 764                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 765                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 766              }                                                                                                     
 767              return;                                                                                               
 768          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 769              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 770                  mWorkspace.exitOverviewMode(false);                                                               

 771              }                                                                                                     
 772              return;                                                                                               
 773          }                                                                                                         
 774                                                                                                                    
 775          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 776                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 777                                                                                                                    
 778          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 779          // We have special handling for widgets                                                                   
 780          if (isWidgetDrop) {                                                                                       
 781              final int appWidgetId;                                                                                
 782              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 783                      : -1;                                                                                         
 784              if (widgetId < 0) {                                                                                   
 785                  appWidgetId = pendingAddWidgetId;                                                                 
 786              } else {                                                                                              
 787                  appWidgetId = widgetId;                                                                           
 788              }                                                                                                     
 789                                                                                                                    
 790              final int result;                                                                                     
 791              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 792                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 793                          "returned from the widget configuration activity.");                                      
 794                  result = RESULT_CANCELED;                                                                         
 795                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 796                  final Runnable onComplete = new Runnable() {                                                      
 797                      @Override                                                                                     
 798                      public void run() {                                                                           
 799                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 800                      }                                                                                             
 801                  };                                                                                                
 802                  if (workspaceLocked) {                                                                            
 803                      // No need to remove the empty screen if we're mid-binding, as the                            
 804                      // the bind will not add the empty screen.                                                    
 805                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 806                  } else {                                                                                          
 807                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 808                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 809                  }                                                                                                 
 810              } else {                                                                                              
 811                  if (!workspaceLocked) {                                                                           
 812                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 813                          // When the screen id represents an actual screen (as opposed to a rank)                  
 814                          // we make sure that the drop page actually exists.                                       
 815                          mPendingAddInfo.screenId =                                                                
 816                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 817                      }                                                                                             
 818                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 819                                                                                                                    
 820                      dropLayout.setDropPending(true);                                                              
 821                      final Runnable onComplete = new Runnable() {                                                  
 822                          @Override                                                                                 
 823                          public void run() {                                                                       
 824                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 825                              dropLayout.setDropPending(false);                                                     
 826                          }                                                                                         
 827                      };                                                                                            
 828                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 829                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 830                  } else {                                                                                          
 831                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 832                              mPendingAddInfo);                                                                     
 833                      sPendingAddItem = args;                                                                       
 834                  }                                                                                                 
 835              }                                                                                                     
 836              return;                                                                                               
 837          }                                                                                                         
 838                                                                                                                    
 839          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 840              if (resultCode == RESULT_OK) {                                                                        
 841                  // Update the widget view.                                                                        
 842                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 843                          pendingAddWidgetId, mPendingAddInfo);                                                     
 844                  if (workspaceLocked) {                                                                            
 845                      sPendingAddItem = args;                                                                       
 846                  } else {                                                                                          
 847                      completeAdd(args);                                                                            
 848                  }                                                                                                 
 849              }                                                                                                     
 850              // Leave the widget in the pending state if the user canceled the configure.                          
 851              return;                                                                                               
 852          }                                                                                                         
 853                                                                                                                    
 854          // The pattern used here is that a user PICKs a specific application,                                     
 855          // which, depending on the target, might need to CREATE the actual target.                                
 856                                                                                                                    
 857          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 858          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 859          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 860              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 861                      mPendingAddInfo);                                                                             
 862              if (isWorkspaceLocked()) {                                                                            
 863                  sPendingAddItem = args;                                                                           
 864              } else {                                                                                              
 865                  completeAdd(args);                                                                                
 866                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 867                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 868              }                                                                                                     
 869          } else if (resultCode == RESULT_CANCELED) {                                                               
 870              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 871                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 872          }                                                                                                         
 873          mDragLayer.clearAnimatedView();                                                                           
 874                                                                                                                    
 875      }                                                                                                             
 876                                                                                                                    
 877      @Override                                                                                                     
 878      protected void onActivityResult(                                                                              
 879              final int requestCode, final int resultCode, final Intent data) {                                     
 880          handleActivityResult(requestCode, resultCode, data);                                                      
 881          if (mLauncherCallbacks != null) {                                                                         
 882              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 883          }                                                                                                         
 884      }                                                                                                             
 885                                                                                                                    
 886      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 887              appWidgetId, ItemInfo info) {                                                                         
 888          PendingAddArguments args = new PendingAddArguments();                                                     
 889          args.requestCode = requestCode;                                                                           
 890          args.intent = data;                                                                                       
 891          args.container = info.container;                                                                          
 892          args.screenId = info.screenId;                                                                            
 893          args.cellX = info.cellX;                                                                                  
 894          args.cellY = info.cellY;                                                                                  
 895          args.appWidgetId = appWidgetId;                                                                           
 896          return args;                                                                                              
 897      }                                                                                                             
 898                                                                                                                    
 899      /**                                                                                                           
 900       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 901       *                                                                                                            
 902       * @param screenId the screen id to check                                                                     
 903       * @return the new screen, or screenId if it exists                                                           
 904       */                                                                                                           
 905      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 906          CellLayout dropLayout =                                                                                   
 907                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 908          if (dropLayout == null) {                                                                                 
 909              // it's possible that the add screen was removed because it was                                       
 910              // empty and a re-bind occurred                                                                       
 911              mWorkspace.addExtraEmptyScreen();                                                                     
 912              return mWorkspace.commitExtraEmptyScreen();                                                           
 913          } else {                                                                                                  
 914              return screenId;                                                                                      
 915          }                                                                                                         
 916      }                                                                                                             
 917                                                                                                                    
 918      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        

 919          CellLayout cellLayout =                                                                                   
 920                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 921          Runnable onCompleteRunnable = null;                                                                       
 922          int animationType = 0;                                                                                    
 923                                                                                                                    
 924          AppWidgetHostView boundWidget = null;                                                                     
 925          if (resultCode == RESULT_OK) {                                                                            
 926              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 927              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 928                      mPendingAddWidgetInfo);                                                                       
 929              boundWidget = layout;                                                                                 
 930              onCompleteRunnable = new Runnable() {                                                                 
 931                  @Override                                                                                         
 932                  public void run() {                                                                               
 933                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 934                              mPendingAddInfo.screenId, layout, null);                                              
 935                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 936                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 937                  }                                                                                                 
 938              };                                                                                                    
 939          } else if (resultCode == RESULT_CANCELED) {                                                               
 940              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 941              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 942          }                                                                                                         
 943          if (mDragLayer.getAnimatedView() != null) {                                                               
 944              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 945                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 946                      animationType, boundWidget, true);                                                            
 947          } else if (onCompleteRunnable != null) {                                                                  
 948              // The animated view may be null in the case of a rotation during widget configuration                
 949              onCompleteRunnable.run();                                                                             
 950          }                                                                                                         
 951      }                                                                                                             
 952                                                                                                                    
 953      @Override                                                                                                     
 954      protected void onStop() {                                                                                     
 955          super.onStop();                                                                                           
 956          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 957                                                                                                                    
 958          if (mLauncherCallbacks != null) {                                                                         
 959              mLauncherCallbacks.onStop();                                                                          
 960          }                                                                                                         
 961      }                                                                                                             
 962                                                                                                                    
 963      @Override                                                                                                     
 964      protected void onStart() {                                                                                    
 965          super.onStart();                                                                                          
 966          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 967                                                                                                                    
 968          if (mLauncherCallbacks != null) {                                                                         
 969              mLauncherCallbacks.onStart();                                                                         
 970          }                                                                                                         
 971      }                                                                                                             
 972                                                                                                                    
 973      @Override                                                                                                     
 974      protected void onResume() {                                                                                   
 975          long startTime = 0;                                                                                       
 976          if (DEBUG_RESUME_TIME) {                                                                                  
 977              startTime = System.currentTimeMillis();                                                               
 978              Log.v(TAG, "Launcher.onResume()");                                                                    
 979          }                                                                                                         
 980                                                                                                                    
 981          if (mLauncherCallbacks != null) {                                                                         
 982              mLauncherCallbacks.preOnResume();                                                                     
 983          }                                                                                                         
 984                                                                                                                    
 985          super.onResume();                                                                                         
 986                                                                                                                    
 987          // Restore the previous launcher state                                                                    
 988          if (mOnResumeState == State.WORKSPACE) {                                                                  
 989              showWorkspace(false);                                                                                 
 990          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
 991              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    









 992          }                                                                                                         
 993          mOnResumeState = State.NONE;                                                                              
 994                                                                                                                    
 995          // Background was set to gradient in onPause(), restore to black if in all apps.                          
 996          setWorkspaceBackground(mState == State.WORKSPACE);                                                        













 997                                                                                                                    
 998          mPaused = false;                                                                                          
 999          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1000              setWorkspaceLoading(true);                                                                            
1001              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             

1002              mRestoring = false;                                                                                   
1003              mOnResumeNeedsLoad = false;                                                                           
1004          }                                                                                                         
1005          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1006              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1007              // execute them here                                                                                  
1008              long startTimeCallbacks = 0;                                                                          
1009              if (DEBUG_RESUME_TIME) {                                                                              
1010                  startTimeCallbacks = System.currentTimeMillis();                                                  
1011              }                                                                                                     
1012                                                                                                                    
1013              if (mAppsCustomizeContent != null) {                                                                  
1014                  mAppsCustomizeContent.setBulkBind(true);                                                          
1015              }                                                                                                     
1016              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1017                  mBindOnResumeCallbacks.get(i).run();                                                              
1018              }                                                                                                     
1019              if (mAppsCustomizeContent != null) {                                                                  
1020                  mAppsCustomizeContent.setBulkBind(false);                                                         
1021              }                                                                                                     
1022              mBindOnResumeCallbacks.clear();                                                                       
1023              if (DEBUG_RESUME_TIME) {                                                                              
1024                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1025                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1026              }                                                                                                     
1027          }                                                                                                         
1028          if (mOnResumeCallbacks.size() > 0) {                                                                      
1029              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1030                  mOnResumeCallbacks.get(i).run();                                                                  
1031              }                                                                                                     
1032              mOnResumeCallbacks.clear();                                                                           
1033          }                                                                                                         
1034                                                                                                                    
1035          // Reset the pressed state of icons that were locked in the press state while activities                  
1036          // were launching                                                                                         
1037          if (mWaitingForResume != null) {                                                                          
1038              // Resets the previous workspace icon press state                                                     
1039              mWaitingForResume.setStayPressed(false);                                                              
1040          }                                                                                                         
1041                                                                                                                    
1042          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1043          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1044          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1045          // orientation.                                                                                           
1046          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1047                                                                                                                    
1048          // Process any items that were added while Launcher was away.                                             
1049          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                

1050                                                                                                                    
1051          if (DEBUG_RESUME_TIME) {                                                                                  
1052              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1053          }                                                                                                         
1054                                                                                                                    
1055          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1056              // If we are resuming and the custom content is the current page, we call onShow().                   
1057              // It is also poassible that onShow will instead be called slightly after first layout                
1058              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1059              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1060                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1061              }                                                                                                     
1062          }                                                                                                         
1063          mWorkspace.updateInteractionForState();                                                                   

1064          mWorkspace.onResume();                                                                                    
1065                                                                                                                    
1066          PackageInstallerCompat.getInstance(this).onResume();                                                      




1067                                                                                                                    
1068          if (mLauncherCallbacks != null) {                                                                         
1069              mLauncherCallbacks.onResume();                                                                        
1070          }                                                                                                         
1071      }                                                                                                             
1072                                                                                                                    
1073      @Override                                                                                                     
1074      protected void onPause() {                                                                                    
1075          // Ensure that items added to Launcher are queued until Launcher returns                                  
1076          InstallShortcutReceiver.enableInstallQueue();                                                             
1077          PackageInstallerCompat.getInstance(this).onPause();                                                       
1078                                                                                                                    
1079          super.onPause();                                                                                          
1080          mPaused = true;                                                                                           
1081          mDragController.cancelDrag();                                                                             
1082          mDragController.resetLastGestureUpTime();                                                                 
1083                                                                                                                    
1084          // We call onHide() aggressively. The custom content callbacks should be able to                          
1085          // debounce excess onHide calls.                                                                          
1086          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1087              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1088          }                                                                                                         
1089                                                                                                                    
1090          if (mLauncherCallbacks != null) {                                                                         
1091              mLauncherCallbacks.onPause();                                                                         
1092          }                                                                                                         
1093      }                                                                                                             
1094                                                                                                                    
1095      public interface CustomContentCallbacks {                                                                     
1096          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1097          // by a onResume or by scrolling otherwise.                                                               
1098          public void onShow(boolean fromResume);                                                                   
1099                                                                                                                    
1100          // Custom content is completely hidden                                                                    
1101          public void onHide();                                                                                     
1102                                                                                                                    
1103          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1104          public void onScrollProgressChanged(float progress);                                                      
1105                                                                                                                    
1106          // Indicates whether the user is allowed to scroll away from the custom content.                          
1107          boolean isScrollingAllowed();                                                                             
1108      }                                                                                                             
1109                                                                                                                    
1110      public interface LauncherOverlay {                                                                            
1111                                                                                                                    
1112          /**                                                                                                       
1113           * Touch interaction leading to overscroll has begun                                                      
1114           */                                                                                                       
1115          public void onScrollInteractionBegin();                                                                   
1116                                                                                                                    
1117          /**                                                                                                       
1118           * Touch interaction related to overscroll has ended                                                      
1119           */                                                                                                       
1120          public void onScrollInteractionEnd();                                                                     
1121                                                                                                                    
1122          /**                                                                                                       
1123           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1124           * screen (or in the case of RTL, the rightmost screen).                                                  
1125           */                                                                                                       
1126          public void onScrollChange(int progress, boolean rtl);                                                    
1127                                                                                                                    
1128          /**                                                                                                       
1129           * Screen has stopped scrolling                                                                           
1130           */                                                                                                       
1131          public void onScrollSettled();                                                                            
1132                                                                                                                    
1133          /**                                                                                                       
1134           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1135           * to exit fully immersive mode.                                                                          
1136           */                                                                                                       
1137          public void forceExitFullImmersion();                                                                     













1138      }                                                                                                             
1139                                                                                                                    
1140      public interface LauncherOverlayCallbacks {                                                                   
1141          /**                                                                                                       
1142           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1143           * however it doesn't modify any state within the launcher.                                               
1144           */                                                                                                       
1145          public boolean canEnterFullImmersion();                                                                   
1146                                                                                                                    
1147          /**                                                                                                       
1148           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1149           * eg. by occupying the full screen and handling all touch events.                                        
1150           *                                                                                                        
1151           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1152           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1153           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1154           *                                                                                                        
1155           */                                                                                                       
1156          public boolean enterFullImmersion();                                                                      
1157                                                                                                                    
1158          /**                                                                                                       
1159           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1160           * full control over UI and state.                                                                        
1161           */                                                                                                       
1162          public void exitFullImmersion();                                                                          
1163      }                                                                                                             
1164                                                                                                                    
1165      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1166                                                                                                                    
1167          @Override                                                                                                 
1168          public boolean canEnterFullImmersion() {                                                                  
1169              return mState == State.WORKSPACE;                                                                     
1170          }                                                                                                         
1171                                                                                                                    
1172          @Override                                                                                                 
1173          public boolean enterFullImmersion() {                                                                     
1174              if (mState == State.WORKSPACE) {                                                                      
1175                  // When fully immersed, disregard any touches which fall through.                                 
1176                  mDragLayer.setBlockTouch(true);                                                                   
1177                  return true;                                                                                      
1178              }                                                                                                     
1179              return false;                                                                                         
1180          }                                                                                                         
1181                                                                                                                    
1182          @Override                                                                                                 
1183          public void exitFullImmersion() {                                                                         
1184              mDragLayer.setBlockTouch(false);                                                                      
1185          }                                                                                                         
1186      }                                                                                                             
1187                                                                                                                    
1188      protected boolean hasSettings() {                                                                             
1189          if (mLauncherCallbacks != null) {                                                                         
1190              return mLauncherCallbacks.hasSettings();                                                              
1191          }                                                                                                         
1192          return false;                                                                                             
1193      }                                                                                                             
1194                                                                                                                    
1195                                                                                                                    
1196      public void addToCustomContentPage(View customContent,                                                        
1197              CustomContentCallbacks callbacks, String description) {                                               
1198          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1199      }                                                                                                             
1200                                                                                                                    
1201      // The custom content needs to offset its content to account for the QSB                                      
1202      public int getTopOffsetForCustomContent() {                                                                   
1203          return mWorkspace.getPaddingTop();                                                                        
1204      }                                                                                                             
1205                                                                                                                    
1206      @Override                                                                                                     
1207      public Object onRetainNonConfigurationInstance() {                                                            
1208          // Flag the loader to stop early before switching                                                         
1209          if (mModel.isCurrentCallbacks(this)) {                                                                    
1210              mModel.stopLoader();                                                                                  
1211          }                                                                                                         
1212          if (mAppsCustomizeContent != null) {                                                                      
1213              mAppsCustomizeContent.surrender();                                                                    
1214          }                                                                                                         


1215          return Boolean.TRUE;                                                                                      
1216      }                                                                                                             
1217                                                                                                                    
1218      // We can't hide the IME if it was forced open.  So don't bother                                              
1219      @Override                                                                                                     
1220      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1221          super.onWindowFocusChanged(hasFocus);                                                                     
1222          mHasFocus = hasFocus;                                                                                     
1223                                                                                                                    
1224          if (mLauncherCallbacks != null) {                                                                         
1225              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1226          }                                                                                                         
1227      }                                                                                                             
1228                                                                                                                    
1229      private boolean acceptFilter() {                                                                              
1230          final InputMethodManager inputManager = (InputMethodManager)                                              
1231                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1232          return !inputManager.isFullscreenMode();                                                                  
1233      }                                                                                                             
1234                                                                                                                    
1235      @Override                                                                                                     
1236      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1237          final int uniChar = event.getUnicodeChar();                                                               
1238          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1239          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1240          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1241              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1242                      keyCode, event);                                                                              
1243              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1244                  // something usable has been typed - start a search                                               
1245                  // the typed text will be retrieved and cleared by                                                
1246                  // showSearchDialog()                                                                             
1247                  // If there are multiple keystrokes before the search dialog takes focus,                         
1248                  // onSearchRequested() will be called for every keystroke,                                        
1249                  // but it is idempotent, so it's fine.                                                            
1250                  return onSearchRequested();                                                                       
1251              }                                                                                                     
1252          }                                                                                                         
1253                                                                                                                    
1254          // Eat the long press event so the keyboard doesn't come up.                                              
1255          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1256              return true;                                                                                          
1257          }                                                                                                         
1258                                                                                                                    
1259          return handled;                                                                                           
1260      }                                                                                                             
1261                                                                                                                    
1262      private String getTypedText() {                                                                               
1263          return mDefaultKeySsb.toString();                                                                         
1264      }                                                                                                             
1265                                                                                                                    
1266      private void clearTypedText() {                                                                               
1267          mDefaultKeySsb.clear();                                                                                   
1268          mDefaultKeySsb.clearSpans();                                                                              
1269          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1270      }                                                                                                             
1271                                                                                                                    
1272      /**                                                                                                           
1273       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1274       * State                                                                                                      
1275       */                                                                                                           
1276      private static State intToState(int stateOrdinal) {                                                           
1277          State state = State.WORKSPACE;                                                                            
1278          final State[] stateValues = State.values();                                                               
1279          for (int i = 0; i < stateValues.length; i++) {                                                            
1280              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1281                  state = stateValues[i];                                                                           
1282                  break;                                                                                            
1283              }                                                                                                     
1284          }                                                                                                         
1285          return state;                                                                                             
1286      }                                                                                                             
1287                                                                                                                    
1288      /**                                                                                                           
1289       * Restores the previous state, if it exists.                                                                 
1290       *                                                                                                            
1291       * @param savedState The previous state.                                                                      
1292       */                                                                                                           
1293      @SuppressWarnings("unchecked")                                                                                
1294      private void restoreState(Bundle savedState) {                                                                
1295          if (savedState == null) {                                                                                 
1296              return;                                                                                               
1297          }                                                                                                         
1298                                                                                                                    
1299          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1300          if (state == State.APPS_CUSTOMIZE) {                                                                      
1301              mOnResumeState = State.APPS_CUSTOMIZE;                                                                


1302          }                                                                                                         
1303                                                                                                                    
1304          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1305                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1306          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1307              mWorkspace.setRestorePage(currentScreen);                                                             
1308          }                                                                                                         
1309                                                                                                                    
1310          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1311          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1312                                                                                                                    
1313          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1314              mPendingAddInfo.container = pendingAddContainer;                                                      
1315              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1316              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1317              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1318              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1319              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1320              AppWidgetProviderInfo info = savedState.getParcelable(                                                
1321                      RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                                       
1322              mPendingAddWidgetInfo = info == null ?                                                                
1323                      null : LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                            
1324                                                                                                                    
1325              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1326              setWaitingForResult(true);                                                                            
1327              mRestoring = true;                                                                                    
1328          }                                                                                                         
1329                                                                                                                    
1330          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1331          if (renameFolder) {                                                                                       
1332              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1333              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1334              mRestoring = true;                                                                                    
1335          }                                                                                                         
1336                                                                                                                    
1337          // Restore the AppsCustomize tab                                                                          
1338          if (mAppsCustomizeTabHost != null) {                                                                      
1339              String curTab = savedState.getString("apps_customize_currentTab");                                    
1340              if (curTab != null) {                                                                                 
1341                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1342                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1343                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1344                          mAppsCustomizeContent.getCurrentPage());                                                  
1345              }                                                                                                     
1346                                                                                                                    
1347              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1348              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1349          }                                                                                                         
1350          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1351                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1352      }                                                                                                             
1353                                                                                                                    
1354      /**                                                                                                           
1355       * Finds all the views we need and configure them properly.                                                   
1356       */                                                                                                           
1357      private void setupViews() {                                                                                   
1358          final DragController dragController = mDragController;                                                    
1359                                                                                                                    
1360          mLauncherView = findViewById(R.id.launcher);                                                              
1361          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1362          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1363          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1364          mWorkspace.setPageSwitchListener(this);                                                                   
1365          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1366                                                                                                                    
1367          mLauncherView.setSystemUiVisibility(                                                                      
1368                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1369          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1370                                                                                                                    
1371          // Setup the drag layer                                                                                   
1372          mDragLayer.setup(this, dragController);                                                                   
1373                                                                                                                    
1374          // Setup the hotseat                                                                                      
1375          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1376          if (mHotseat != null) {                                                                                   
1377              mHotseat.setup(this);                                                                                 
1378              mHotseat.setOnLongClickListener(this);                                                                
1379          }                                                                                                         
1380                                                                                                                    
1381          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1382          View widgetButton = findViewById(R.id.widget_button);                                                     
1383          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1384              @Override                                                                                             
1385              public void onClick(View arg0) {                                                                      
1386                  if (!mWorkspace.isSwitchingState()) {                                                             
1387                      onClickAddWidgetButton(arg0);                                                                 
1388                  }                                                                                                 
1389              }                                                                                                     
1390          });                                                                                                       
1391          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1392                                                                                                                    
1393          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1394          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1395              @Override                                                                                             
1396              public void onClick(View arg0) {                                                                      
1397                  if (!mWorkspace.isSwitchingState()) {                                                             
1398                      onClickWallpaperPicker(arg0);                                                                 
1399                  }                                                                                                 
1400              }                                                                                                     
1401          });                                                                                                       
1402          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1403                                                                                                                    
1404          View settingsButton = findViewById(R.id.settings_button);                                                 
1405          if (hasSettings()) {                                                                                      
1406              settingsButton.setOnClickListener(new OnClickListener() {                                             
1407                  @Override                                                                                         
1408                  public void onClick(View arg0) {                                                                  
1409                      if (!mWorkspace.isSwitchingState()) {                                                         
1410                          onClickSettingsButton(arg0);                                                              
1411                      }                                                                                             
1412                  }                                                                                                 
1413              });                                                                                                   
1414              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1415          } else {                                                                                                  
1416              settingsButton.setVisibility(View.GONE);                                                              
1417          }                                                                                                         
1418                                                                                                                    
1419          mOverviewPanel.setAlpha(0f);                                                                              
1420                                                                                                                    
1421          // Setup the workspace                                                                                    
1422          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1423          mWorkspace.setOnLongClickListener(this);                                                                  
1424          mWorkspace.setup(dragController);                                                                         
1425          dragController.addDragListener(mWorkspace);                                                               
1426                                                                                                                    
1427          // Get the search/delete bar                                                                              
1428          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1429                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1430                                                                                                                    






1431          // Setup AppsCustomize                                                                                    
1432          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1433          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1434                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1435          mAppsCustomizeContent.setup(this, dragController);                                                        

1436                                                                                                                    
1437          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1438          dragController.setDragScoller(mWorkspace);                                                                
1439          dragController.setScrollView(mDragLayer);                                                                 
1440          dragController.setMoveTarget(mWorkspace);                                                                 
1441          dragController.addDropTarget(mWorkspace);                                                                 
1442          if (mSearchDropTargetBar != null) {                                                                       
1443              mSearchDropTargetBar.setup(this, dragController);                                                     
1444              mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    

1445          }                                                                                                         
1446                                                                                                                    
1447          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1448              Log.v(TAG, "adding WeightWatcher");                                                                   
1449              mWeightWatcher = new WeightWatcher(this);                                                             
1450              mWeightWatcher.setAlpha(0.5f);                                                                        
1451              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1452                      new FrameLayout.LayoutParams(                                                                 
1453                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1454                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1455                              Gravity.BOTTOM)                                                                       
1456              );                                                                                                    
1457                                                                                                                    
1458              boolean show = shouldShowWeightWatcher();                                                             
1459              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1460          }                                                                                                         
1461      }                                                                                                             
1462                                                                                                                    
1463      /**                                                                                                           
1464       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1465       */                                                                                                           
1466      public void setAllAppsButton(View allAppsButton) {                                                            
1467          mAllAppsButton = allAppsButton;                                                                           
1468      }                                                                                                             
1469                                                                                                                    
1470      public View getAllAppsButton() {                                                                              
1471          return mAllAppsButton;                                                                                    
1472      }                                                                                                             
1473                                                                                                                    
1474      /**                                                                                                           
1475       * Creates a view representing a shortcut.                                                                    
1476       *                                                                                                            
1477       * @param info The data structure describing the shortcut.                                                    
1478       *                                                                                                            
1479       * @return A View inflated from R.layout.application.                                                         
1480       */                                                                                                           
1481      View createShortcut(ShortcutInfo info) {                                                                      
1482          return createShortcut(R.layout.application,                                                               
1483                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            

1484      }                                                                                                             
1485                                                                                                                    
1486      /**                                                                                                           
1487       * Creates a view representing a shortcut inflated from the specified resource.                               
1488       *                                                                                                            
1489       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1490       * @param parent The group the shortcut belongs to.                                                           
1491       * @param info The data structure describing the shortcut.                                                    
1492       *                                                                                                            
1493       * @return A View inflated from layoutResId.                                                                  
1494       */                                                                                                           
1495      public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1496          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1497          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   





1498          favorite.setOnClickListener(this);                                                                        
1499          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1500          return favorite;                                                                                          
1501      }                                                                                                             
1502                                                                                                                    
1503      /**                                                                                                           
1504       * Add a shortcut to the workspace.                                                                           
1505       *                                                                                                            
1506       * @param data The intent describing the shortcut.                                                            
1507       * @param cellInfo The position on screen where to create the shortcut.                                       
1508       */                                                                                                           
1509      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1510              int cellY) {                                                                                          
1511          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1512          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1513          CellLayout layout = getCellLayout(container, screenId);                                                   
1514                                                                                                                    
1515          boolean foundCellSpan = false;                                                                            
1516                                                                                                                    
1517          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            

1518          if (info == null) {                                                                                       
1519              return;                                                                                               
1520          }                                                                                                         
1521          final View view = createShortcut(info);                                                                   
1522                                                                                                                    

1523          // First we check if we already know the exact location where we want to add this item.                   
1524          if (cellX >= 0 && cellY >= 0) {                                                                           
1525              cellXY[0] = cellX;                                                                                    
1526              cellXY[1] = cellY;                                                                                    
1527              foundCellSpan = true;                                                                                 
1528                                                                                                                    
1529              // If appropriate, either create a folder or add to an existing folder                                
1530              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1531                      true, null,null)) {                                                                           
1532                  return;                                                                                           
1533              }                                                                                                     
1534              DragObject dragObject = new DragObject();                                                             
1535              dragObject.dragInfo = info;                                                                           
1536              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1537                      true)) {                                                                                      
1538                  return;                                                                                           
1539              }                                                                                                     
1540          } else if (touchXY != null) {                                                                             
1541              // when dragging and dropping, just find the closest free spot                                        
1542              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1543              foundCellSpan = (result != null);                                                                     
1544          } else {                                                                                                  
1545              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1546          }                                                                                                         
1547                                                                                                                    
1548          if (!foundCellSpan) {                                                                                     
1549              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1550              return;                                                                                               
1551          }                                                                                                         
1552                                                                                                                    
1553          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            

1554                                                                                                                    
1555          if (!mRestoring) {                                                                                        
1556              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1557                      isWorkspaceLocked());                                                                         
1558          }                                                                                                         
1559      }                                                                                                             
1560                                                                                                                    
1561      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1562              int minHeight) {                                                                                      
1563          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    


1564          // We want to account for the extra amount of padding that we are adding to the widget                    
1565          // to ensure that it gets the full amount of space that it has requested                                  
1566          int requiredWidth = minWidth + padding.left + padding.right;                                              
1567          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1568          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1569      }                                                                                                             
1570                                                                                                                    
1571      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1572          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1573      }                                                                                                             
1574                                                                                                                    
1575      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1576          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1577      }                                                                                                             
1578                                                                                                                    
1579      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1580          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1581      }                                                                                                             
1582                                                                                                                    
1583      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1584          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1585                  info.minResizeHeight);                                                                            









1586      }                                                                                                             
1587                                                                                                                    
1588      /**                                                                                                           
1589       * Add a widget to the workspace.                                                                             
1590       *                                                                                                            
1591       * @param appWidgetId The app widget id                                                                       
1592       */                                                                                                           
1593      private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             

1594              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1595                                                                                                                    
1596          ItemInfo info = mPendingAddInfo;                                                                          
1597          if (appWidgetInfo == null) {                                                                              
1598              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1599                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1600          }                                                                                                         
1601                                                                                                                    
1602          if (appWidgetInfo.isCustomWidget) {                                                                       
1603              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1604          }                                                                                                         
1605                                                                                                                    
1606          LauncherAppWidgetInfo launcherInfo;                                                                       
1607          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1608          launcherInfo.spanX = info.spanX;                                                                          
1609          launcherInfo.spanY = info.spanY;                                                                          
1610          launcherInfo.minSpanX = info.minSpanX;                                                                    
1611          launcherInfo.minSpanY = info.minSpanY;                                                                    
1612          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1613                                                                                                                    
1614          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1615                  container, screenId, info.cellX, info.cellY, false);                                              

1616                                                                                                                    
1617          if (!mRestoring) {                                                                                        
1618              if (hostView == null) {                                                                               
1619                  // Perform actual inflation because we're live                                                    
1620                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1621                          appWidgetInfo);                                                                           
1622              } else {                                                                                              
1623                  // The AppWidgetHostView has already been inflated and instantiated                               
1624                  launcherInfo.hostView = hostView;                                                                 
1625              }                                                                                                     
1626              launcherInfo.hostView.setTag(launcherInfo);                                                           
1627              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1628              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1629                                                                                                                    
1630              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1631                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1632                                                                                                                    
1633              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1634          }                                                                                                         
1635          resetAddInfo();                                                                                           
1636      }                                                                                                             
1637                                                                                                                    
1638      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1639          @Override                                                                                                 
1640          public void onReceive(Context context, Intent intent) {                                                   
1641              final String action = intent.getAction();                                                             
1642              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1643                  mUserPresent = false;                                                                             
1644                  mDragLayer.clearAllResizeFrames();                                                                
1645                  updateRunning();                                                                                  

1646                                                                                                                    
1647                  // Reset AllApps to its initial state only if we are not in the middle of                         
1648                  // processing a multi-step drop                                                                   
1649                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               


1650                      showWorkspace(false);                                                                         
1651                  }                                                                                                 
1652              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1653                  mUserPresent = true;                                                                              
1654                  updateRunning();                                                                                  

1655              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1656                  mModel.resetLoadedState(false, true);                                                             
1657                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         

1658                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1659              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1660                  mModel.resetLoadedState(false, true);                                                             
1661                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         

1662                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1663                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1664              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1665                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1666                  getModel().forceReload();                                                                         
1667              }                                                                                                     
1668          }                                                                                                         
1669      };                                                                                                            
1670                                                                                                                    
1671      @Override                                                                                                     
1672      public void onAttachedToWindow() {                                                                            
1673          super.onAttachedToWindow();                                                                               
1674                                                                                                                    
1675          // Listen for broadcasts related to user-presence                                                         
1676          final IntentFilter filter = new IntentFilter();                                                           
1677          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1678          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1679          // For handling managed profiles                                                                          
1680          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1681          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1682          if (ENABLE_DEBUG_INTENTS) {                                                                               
1683              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1684              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1685          }                                                                                                         
1686          registerReceiver(mReceiver, filter);                                                                      
1687          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1688          setupTransparentSystemBarsForLmp();                                                                       
1689          mAttached = true;                                                                                         
1690          mVisible = true;                                                                                          
1691      }                                                                                                             
1692                                                                                                                    
1693      /**                                                                                                           
1694       * Sets up transparent navigation and status bars in LMP.                                                     
1695       * This method is a no-op for other platform versions.                                                        
1696       */                                                                                                           
1697      @TargetApi(19)                                                                                                

1698      private void setupTransparentSystemBarsForLmp() {                                                             
1699          // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1700          // Currently we use reflection to access the flags and the API to set the transparency                    
1701          // on the System bars.                                                                                    
1702          if (Utilities.isLmpOrAbove()) {                                                                           
1703              try {                                                                                                 
1704                  getWindow().getAttributes().systemUiVisibility |=                                                 
1705                          (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1706                                  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1707                                  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1708                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1709                          | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1710                  Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1711                          "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1712                  getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1713                                                                                                                    
1714                  Method setStatusBarColorMethod =                                                                  
1715                          Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1716                  Method setNavigationBarColorMethod =                                                              
1717                          Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1718                  setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1719                  setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1720              } catch (NoSuchFieldException e) {                                                                    
1721                  Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1722              } catch (NoSuchMethodException ex) {                                                                  
1723                  Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1724              } catch (IllegalAccessException e) {                                                                  
1725                  Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1726              } catch (IllegalArgumentException e) {                                                                
1727                  Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1728              } catch (InvocationTargetException e) {                                                               
1729                  Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1730              } finally {}                                                                                          










1731          }                                                                                                         
1732      }                                                                                                             
1733                                                                                                                    
1734      @Override                                                                                                     
1735      public void onDetachedFromWindow() {                                                                          
1736          super.onDetachedFromWindow();                                                                             
1737          mVisible = false;                                                                                         
1738                                                                                                                    
1739          if (mAttached) {                                                                                          
1740              unregisterReceiver(mReceiver);                                                                        
1741              mAttached = false;                                                                                    
1742          }                                                                                                         
1743          updateRunning();                                                                                          

1744      }                                                                                                             
1745                                                                                                                    
1746      public void onWindowVisibilityChanged(int visibility) {                                                       
1747          mVisible = visibility == View.VISIBLE;                                                                    
1748          updateRunning();                                                                                          

1749          // The following code used to be in onResume, but it turns out onResume is called when                    
1750          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1751          // is a more appropriate event to handle                                                                  
1752          if (mVisible) {                                                                                           
1753              mAppsCustomizeTabHost.onWindowVisible();                                                              
1754              if (!mWorkspaceLoading) {                                                                             
1755                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1756                  // We want to let Launcher draw itself at least once before we force it to build                  
1757                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1758                  // apps is nice and speedy.                                                                       
1759                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1760                      private boolean mStarted = false;                                                             
1761                      public void onDraw() {                                                                        
1762                          if (mStarted) return;                                                                     
1763                          mStarted = true;                                                                          
1764                          // We delay the layer building a bit in order to give                                     
1765                          // other message processing a time to run.  In particular                                 
1766                          // this avoids a delay in hiding the IME if it was                                        
1767                          // currently shown, because doing that may involve                                        
1768                          // some communication back with the app.                                                  
1769                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1770                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1771                          mWorkspace.post(new Runnable() {                                                          
1772                                  public void run() {                                                               
1773                                      if (mWorkspace != null &&                                                     
1774                                              mWorkspace.getViewTreeObserver() != null) {                           
1775                                          mWorkspace.getViewTreeObserver().                                         
1776                                                  removeOnDrawListener(listener);                                   
1777                                      }                                                                             
1778                                  }                                                                                 
1779                              });                                                                                   
1780                          return;                                                                                   
1781                      }                                                                                             
1782                  });                                                                                               
1783              }                                                                                                     
1784              clearTypedText();                                                                                     
1785          }                                                                                                         
1786      }                                                                                                             
1787                                                                                                                    
1788      private void sendAdvanceMessage(long delay) {                                                                 

1789          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1790          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1791          mHandler.sendMessageDelayed(msg, delay);                                                                  
1792          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1793      }                                                                                                             
1794                                                                                                                    
1795      private void updateRunning() {                                                                                

1796          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1797          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1798              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1799              if (autoAdvanceRunning) {                                                                             
1800                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1801                  sendAdvanceMessage(delay);                                                                        
1802              } else {                                                                                              
1803                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1804                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1805                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1806                  }                                                                                                 
1807                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1808                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1809              }                                                                                                     
1810          }                                                                                                         
1811      }                                                                                                             
1812                                                                                                                    
1813      private final Handler mHandler = new Handler() {                                                              
1814          @Override                                                                                                 
1815          public void handleMessage(Message msg) {                                                                  
1816              if (msg.what == ADVANCE_MSG) {                                                                        
1817                  int i = 0;                                                                                        
1818                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1819                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1820                      final int delay = mAdvanceStagger * i;                                                        
1821                      if (v instanceof Advanceable) {                                                               
1822                         postDelayed(new Runnable() {                                                               
1823                             public void run() {                                                                    
1824                                 ((Advanceable) v).advance();                                                       
1825                             }                                                                                      
1826                         }, delay);                                                                                 
1827                      }                                                                                             
1828                      i++;                                                                                          
1829                  }                                                                                                 
1830                  sendAdvanceMessage(mAdvanceInterval);                                                             
1831              }                                                                                                     
1832          }                                                                                                         
1833      };                                                                                                            
1834                                                                                                                    
1835      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1836          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1837          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1838          if (v instanceof Advanceable) {                                                                           
1839              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1840              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1841              updateRunning();                                                                                      

1842          }                                                                                                         
1843      }                                                                                                             
1844                                                                                                                    
1845      void removeWidgetToAutoAdvance(View hostView) {                                                               
1846          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1847              mWidgetsToAdvance.remove(hostView);                                                                   
1848              updateRunning();                                                                                      

1849          }                                                                                                         
1850      }                                                                                                             
1851                                                                                                                    
1852      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1853          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1854          launcherInfo.hostView = null;                                                                             
1855      }                                                                                                             
1856                                                                                                                    
1857      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         

1858          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1859          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1860      }                                                                                                             
1861                                                                                                                    
1862      public ArrayList<AppInfo> getAllAppsList() {                                                                  
1863          return mAppsCustomizeContent.getApps();                                                                   
1864      }                                                                                                             
1865                                                                                                                    
1866      public DragLayer getDragLayer() {                                                                             
1867          return mDragLayer;                                                                                        
1868      }                                                                                                             
1869                                                                                                                    








1870      public Workspace getWorkspace() {                                                                             
1871          return mWorkspace;                                                                                        
1872      }                                                                                                             
1873                                                                                                                    
1874      public Hotseat getHotseat() {                                                                                 
1875          return mHotseat;                                                                                          
1876      }                                                                                                             
1877                                                                                                                    
1878      public ViewGroup getOverviewPanel() {                                                                         
1879          return mOverviewPanel;                                                                                    
1880      }                                                                                                             
1881                                                                                                                    
1882      public SearchDropTargetBar getSearchBar() {                                                                   
1883          return mSearchDropTargetBar;                                                                              
1884      }                                                                                                             
1885                                                                                                                    
1886      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1887          return mAppWidgetHost;                                                                                    
1888      }                                                                                                             
1889                                                                                                                    
1890      public LauncherModel getModel() {                                                                             
1891          return mModel;                                                                                            
1892      }                                                                                                             
1893                                                                                                                    
1894      protected SharedPreferences getSharedPrefs() {                                                                
1895          return mSharedPrefs;                                                                                      




1896      }                                                                                                             
1897                                                                                                                    
1898      public void closeSystemDialogs() {                                                                            
1899          getWindow().closeAllPanels();                                                                             
1900                                                                                                                    
1901          // Whatever we were doing is hereby canceled.                                                             
1902          setWaitingForResult(false);                                                                               
1903      }                                                                                                             
1904                                                                                                                    
1905      @Override                                                                                                     
1906      protected void onNewIntent(Intent intent) {                                                                   
1907          long startTime = 0;                                                                                       
1908          if (DEBUG_RESUME_TIME) {                                                                                  
1909              startTime = System.currentTimeMillis();                                                               
1910          }                                                                                                         
1911          super.onNewIntent(intent);                                                                                
1912                                                                                                                    
1913          // Close the menu                                                                                         
1914          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1915              // also will cancel mWaitingForResult.                                                                
1916              closeSystemDialogs();                                                                                 
1917                                                                                                                    
1918              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1919                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1920                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1921                                                                                                                    
1922              if (mWorkspace == null) {                                                                             
1923                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1924                  return;                                                                                           
1925              }                                                                                                     
1926              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1927              // In all these cases, only animate if we're already on home                                          
1928              mWorkspace.exitWidgetResizeMode();                                                                    
1929                                                                                                                    
1930              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
1931                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
1932              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1933                      openFolder == null && moveToDefaultScreen) {                                                  
1934                  mWorkspace.moveToDefaultScreen(true);                                                             
1935              }                                                                                                     
1936                                                                                                                    
1937              closeFolder();                                                                                        
1938              exitSpringLoadedDragMode();                                                                           
1939                                                                                                                    
1940              // If we are already on home, then just animate back to the workspace,                                
1941              // otherwise, just wait until onResume to set the state back to Workspace                             
1942              if (alreadyOnHome) {                                                                                  
1943                  showWorkspace(true);                                                                              
1944              } else {                                                                                              
1945                  mOnResumeState = State.WORKSPACE;                                                                 
1946              }                                                                                                     
1947                                                                                                                    
1948              final View v = getWindow().peekDecorView();                                                           
1949              if (v != null && v.getWindowToken() != null) {                                                        
1950                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
1951                          INPUT_METHOD_SERVICE);                                                                    
1952                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
1953              }                                                                                                     
1954                                                                                                                    
1955              // Reset the apps customize page                                                                      
1956              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
1957                  mAppsCustomizeTabHost.reset();                                                                    








1958              }                                                                                                     
1959                                                                                                                    
1960              if (mLauncherCallbacks != null) {                                                                     
1961                  mLauncherCallbacks.onHomeIntent();                                                                
1962              }                                                                                                     
1963          }                                                                                                         
1964                                                                                                                    
1965          if (DEBUG_RESUME_TIME) {                                                                                  
1966              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
1967          }                                                                                                         
1968                                                                                                                    
1969          if (mLauncherCallbacks != null) {                                                                         
1970              mLauncherCallbacks.onNewIntent(intent);                                                               
1971          }                                                                                                         
1972      }                                                                                                             
1973                                                                                                                    
1974      @Override                                                                                                     
1975      public void onRestoreInstanceState(Bundle state) {                                                            
1976          super.onRestoreInstanceState(state);                                                                      
1977          for (int page: mSynchronouslyBoundPages) {                                                                
1978              mWorkspace.restoreInstanceStateForChild(page);                                                        
1979          }                                                                                                         
1980      }                                                                                                             
1981                                                                                                                    
1982      @Override                                                                                                     
1983      protected void onSaveInstanceState(Bundle outState) {                                                         
1984          if (mWorkspace.getChildCount() > 0) {                                                                     
1985              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
1986                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
1987          }                                                                                                         
1988          super.onSaveInstanceState(outState);                                                                      
1989                                                                                                                    
1990          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
1991          // We close any open folder since it will not be re-opened, and we need to make sure                      
1992          // this state is reflected.                                                                               
1993          closeFolder();                                                                                            
1994                                                                                                                    
1995          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
1996                  mWaitingForResult) {                                                                              
1997              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
1998              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
1999              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
2000              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
2001              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2002              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2003              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2004              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2005          }                                                                                                         
2006                                                                                                                    
2007          if (mFolderInfo != null && mWaitingForResult) {                                                           
2008              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2009              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2010          }                                                                                                         
2011                                                                                                                    
2012          // Save the current AppsCustomize tab                                                                     
2013          if (mAppsCustomizeTabHost != null) {                                                                      
2014              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2015              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2016              if (currentTabTag != null) {                                                                          
2017                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
2018              }                                                                                                     
2019              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2020              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2021          }                                                                                                         


2022          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2023                                                                                                                    
2024          if (mLauncherCallbacks != null) {                                                                         
2025              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2026          }                                                                                                         
2027      }                                                                                                             
2028                                                                                                                    
2029      @Override                                                                                                     
2030      public void onDestroy() {                                                                                     
2031          super.onDestroy();                                                                                        
2032                                                                                                                    
2033          // Remove all pending runnables                                                                           
2034          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2035          mHandler.removeMessages(0);                                                                               
2036          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2037                                                                                                                    
2038          // Stop callbacks from LauncherModel                                                                      
2039          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2040                                                                                                                    
2041          // It's possible to receive onDestroy after a new Launcher activity has                                   
2042          // been created. In this case, don't interfere with the new Launcher.                                     
2043          if (mModel.isCurrentCallbacks(this)) {                                                                    
2044              mModel.stopLoader();                                                                                  
2045              app.setLauncher(null);                                                                                
2046          }                                                                                                         
2047                                                                                                                    
2048          try {                                                                                                     
2049              mAppWidgetHost.stopListening();                                                                       
2050          } catch (NullPointerException ex) {                                                                       
2051              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2052          }                                                                                                         
2053          mAppWidgetHost = null;                                                                                    
2054                                                                                                                    
2055          mWidgetsToAdvance.clear();                                                                                
2056                                                                                                                    
2057          TextKeyListener.getInstance().release();                                                                  
2058                                                                                                                    
2059          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2060          // to prevent leaking Launcher activities on orientation change.                                          
2061          if (mModel != null) {                                                                                     
2062              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2063          }                                                                                                         
2064                                                                                                                    
2065          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2066          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2067                                                                                                                    
2068          mDragLayer.clearAllResizeFrames();                                                                        
2069          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2070          mWorkspace.removeAllWorkspaceScreens();                                                                   
2071          mWorkspace = null;                                                                                        
2072          mDragController = null;                                                                                   
2073                                                                                                                    
2074          LauncherAnimUtils.onDestroyActivity();                                                                    
2075                                                                                                                    
2076          if (mLauncherCallbacks != null) {                                                                         
2077              mLauncherCallbacks.onDestroy();                                                                       
2078          }                                                                                                         
2079      }                                                                                                             
2080                                                                                                                    
2081      public DragController getDragController() {                                                                   
2082          return mDragController;                                                                                   
2083      }                                                                                                             
2084                                                                                                                    
2085      @Override                                                                                                     
2086      public void startActivityForResult(Intent intent, int requestCode) {                                          
2087          onStartForResult(requestCode);                                                                            
2088          super.startActivityForResult(intent, requestCode);                                                        
2089      }                                                                                                             
2090                                                                                                                    
2091      @Override                                                                                                     
2092      public void startIntentSenderForResult (IntentSender intent, int requestCode,                                 
2093              Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {                
2094          onStartForResult(requestCode);                                                                            
2095          try {                                                                                                     
2096              super.startIntentSenderForResult(intent, requestCode,                                                 
2097                  fillInIntent, flagsMask, flagsValues, extraFlags, options);                                       
2098          } catch (IntentSender.SendIntentException e) {                                                            
2099              throw new ActivityNotFoundException();                                                                
2100          }                                                                                                         
2101      }                                                                                                             
2102                                                                                                                    
2103      private void onStartForResult(int requestCode) {                                                              
2104          if (requestCode >= 0) {                                                                                   
2105              setWaitingForResult(true);                                                                            
2106          }                                                                                                         
2107      }                                                                                                             
2108                                                                                                                    
2109      /**                                                                                                           
2110       * Indicates that we want global search for this activity by setting the globalSearch                         
2111       * argument for {@link #startSearch} to true.                                                                 
2112       */                                                                                                           
2113      @Override                                                                                                     
2114      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2115              Bundle appSearchData, boolean globalSearch) {                                                         
2116                                                                                                                    
2117          showWorkspace(true);                                                                                      
2118                                                                                                                    
2119          if (initialQuery == null) {                                                                               
2120              // Use any text typed in the launcher as the initial query                                            
2121              initialQuery = getTypedText();                                                                        
2122          }                                                                                                         
2123          if (appSearchData == null) {                                                                              
2124              appSearchData = new Bundle();                                                                         
2125              appSearchData.putString("source", "launcher-search");                                                 
2126          }                                                                                                         
2127          Rect sourceBounds = new Rect();                                                                           
2128          if (mSearchDropTargetBar != null) {                                                                       
2129              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2130          }                                                                                                         
2131                                                                                                                    
2132          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2133                  appSearchData, sourceBounds);                                                                     
2134          if (clearTextImmediately) {                                                                               
2135              clearTypedText();                                                                                     
2136          }                                                                                                         



2137      }                                                                                                             
2138                                                                                                                    
2139      /**                                                                                                           
2140       * Start a text search.                                                                                       
2141       *                                                                                                            
2142       * @return {@code true} if the search will start immediately, so any further keypresses                       
2143       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2144       * to buffer keypresses.                                                                                      
2145       */                                                                                                           
2146      public boolean startSearch(String initialQuery,                                                               
2147              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2148          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2149              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2150                      sourceBounds);                                                                                
2151          }                                                                                                         
2152                                                                                                                    
2153          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2154                  appSearchData, sourceBounds);                                                                     
2155          return false;                                                                                             
2156      }                                                                                                             
2157                                                                                                                    
2158      /**                                                                                                           
2159       * Starts the global search activity. This code is a copied from SearchManager                                
2160       */                                                                                                           
2161      private void startGlobalSearch(String initialQuery,                                                           
2162              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2163          final SearchManager searchManager =                                                                       
2164              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2165          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2166          if (globalSearchActivity == null) {                                                                       
2167              Log.w(TAG, "No global search activity found.");                                                       
2168              return;                                                                                               
2169          }                                                                                                         
2170          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2171          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2172          intent.setComponent(globalSearchActivity);                                                                
2173          // Make sure that we have a Bundle to put source in                                                       
2174          if (appSearchData == null) {                                                                              
2175              appSearchData = new Bundle();                                                                         
2176          } else {                                                                                                  
2177              appSearchData = new Bundle(appSearchData);                                                            
2178          }                                                                                                         
2179          // Set source to package name of app that starts global search if not set already.                        
2180          if (!appSearchData.containsKey("source")) {                                                               
2181              appSearchData.putString("source", getPackageName());                                                  
2182          }                                                                                                         
2183          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2184          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2185              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2186          }                                                                                                         
2187          if (selectInitialQuery) {                                                                                 
2188              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2189          }                                                                                                         
2190          intent.setSourceBounds(sourceBounds);                                                                     
2191          try {                                                                                                     
2192              startActivity(intent);                                                                                
2193          } catch (ActivityNotFoundException ex) {                                                                  
2194              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2195          }                                                                                                         
2196      }                                                                                                             
2197                                                                                                                    
2198      public boolean isOnCustomContent() {                                                                          
2199          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2200      }                                                                                                             
2201                                                                                                                    
2202      @Override                                                                                                     
2203      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2204          super.onPrepareOptionsMenu(menu);                                                                         
2205          if (!isOnCustomContent()) {                                                                               
2206              // Close any open folders                                                                             
2207              closeFolder();                                                                                        
2208              // Stop resizing any widgets                                                                          
2209              mWorkspace.exitWidgetResizeMode();                                                                    
2210              if (!mWorkspace.isInOverviewMode()) {                                                                 
2211                  // Show the overview mode                                                                         
2212                  showOverviewMode(true);                                                                           
2213              } else {                                                                                              
2214                  showWorkspace(true);                                                                              
2215              }                                                                                                     
2216          }                                                                                                         
2217          if (mLauncherCallbacks != null) {                                                                         
2218              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2219          }                                                                                                         
2220                                                                                                                    
2221          return false;                                                                                             
2222      }                                                                                                             
2223                                                                                                                    
2224      @Override                                                                                                     
2225      public boolean onSearchRequested() {                                                                          
2226          startSearch(null, false, null, true);                                                                     
2227          // Use a custom animation for launching search                                                            
2228          return true;                                                                                              
2229      }                                                                                                             
2230                                                                                                                    
2231      public boolean isWorkspaceLocked() {                                                                          
2232          return mWorkspaceLoading || mWaitingForResult;                                                            
2233      }                                                                                                             
2234                                                                                                                    
2235      public boolean isWorkspaceLoading() {                                                                         
2236          return mWorkspaceLoading;                                                                                 
2237      }                                                                                                             
2238                                                                                                                    
2239      private void setWorkspaceLoading(boolean value) {                                                             
2240          boolean isLocked = isWorkspaceLocked();                                                                   
2241          mWorkspaceLoading = value;                                                                                
2242          if (isLocked != isWorkspaceLocked()) {                                                                    
2243              onWorkspaceLockedChanged();                                                                           
2244          }                                                                                                         
2245      }                                                                                                             
2246                                                                                                                    
2247      private void setWaitingForResult(boolean value) {                                                             
2248          boolean isLocked = isWorkspaceLocked();                                                                   
2249          mWaitingForResult = value;                                                                                
2250          if (isLocked != isWorkspaceLocked()) {                                                                    
2251              onWorkspaceLockedChanged();                                                                           
2252          }                                                                                                         
2253      }                                                                                                             
2254                                                                                                                    
2255      protected void onWorkspaceLockedChanged() {                                                                   
2256          if (mLauncherCallbacks != null) {                                                                         
2257              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2258          }                                                                                                         
2259      }                                                                                                             
2260                                                                                                                    
2261      private void resetAddInfo() {                                                                                 
2262          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2263          mPendingAddInfo.screenId = -1;                                                                            
2264          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2265          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2266          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2267          mPendingAddInfo.dropPos = null;                                                                           
2268      }                                                                                                             
2269                                                                                                                    
2270      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2271              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2272          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2273      }                                                                                                             
2274                                                                                                                    
2275      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2276              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2277              int delay) {                                                                                          
2278          if (appWidgetInfo.configure != null) {                                                                    
2279              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2280              mPendingAddWidgetId = appWidgetId;                                                                    
2281                                                                                                                    
2282              // Launch over to configure widget, if needed                                                         
2283              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2284                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2285                                                                                                                    
2286          } else {                                                                                                  
2287              // Otherwise just add it                                                                              
2288              Runnable onComplete = new Runnable() {                                                                
2289                  @Override                                                                                         
2290                  public void run() {                                                                               
2291                      // Exit spring loaded mode if necessary after adding the widget                               
2292                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2293                              null);                                                                                
2294                  }                                                                                                 
2295              };                                                                                                    
2296              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2297                      appWidgetInfo);                                                                               
2298              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2299          }                                                                                                         
2300      }                                                                                                             
2301                                                                                                                    
2302      protected void moveToCustomContentScreen(boolean animate) {                                                   
2303          // Close any folders that may be open.                                                                    
2304          closeFolder();                                                                                            
2305          mWorkspace.moveToCustomContentScreen(animate);                                                            
2306      }                                                                                                             
2307                                                                                                                    
2308      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2309              int[] cell, int spanX, int spanY) {                                                                   
2310          switch (info.itemType) {                                                                                  
2311              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2312              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2313                  int span[] = new int[2];                                                                          
2314                  span[0] = spanX;                                                                                  
2315                  span[1] = spanY;                                                                                  
2316                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2317                          container, screenId, cell, span);                                                         
2318                  break;                                                                                            
2319              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2320                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2321                  break;                                                                                            
2322              default:                                                                                              
2323                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2324              }                                                                                                     
2325      }                                                                                                             
2326                                                                                                                    
2327      /**                                                                                                           
2328       * Process a shortcut drop.                                                                                   
2329       *                                                                                                            
2330       * @param componentName The name of the component                                                             
2331       * @param screenId The ID of the screen where it should be added                                              
2332       * @param cell The cell it should be added to, optional                                                       
2333       */                                                                                                           
2334      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2335              int[] cell) {                                                                                         
2336          resetAddInfo();                                                                                           
2337          mPendingAddInfo.container = container;                                                                    
2338          mPendingAddInfo.screenId = screenId;                                                                      
2339          mPendingAddInfo.dropPos = null;                                                                           
2340                                                                                                                    
2341          if (cell != null) {                                                                                       
2342              mPendingAddInfo.cellX = cell[0];                                                                      
2343              mPendingAddInfo.cellY = cell[1];                                                                      
2344          }                                                                                                         
2345                                                                                                                    
2346          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2347          createShortcutIntent.setComponent(componentName);                                                         
2348          processShortcut(createShortcutIntent);                                                                    
2349      }                                                                                                             
2350                                                                                                                    
2351      /**                                                                                                           
2352       * Process a widget drop.                                                                                     
2353       *                                                                                                            
2354       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2355       * @param screenId The ID of the screen where it should be added                                              
2356       * @param cell The cell it should be added to, optional                                                       
2357       */                                                                                                           
2358      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2359              int[] cell, int[] span) {                                                                             
2360          resetAddInfo();                                                                                           
2361          mPendingAddInfo.container = info.container = container;                                                   
2362          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2363          mPendingAddInfo.dropPos = null;                                                                           
2364          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2365          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2366                                                                                                                    
2367          if (cell != null) {                                                                                       
2368              mPendingAddInfo.cellX = cell[0];                                                                      
2369              mPendingAddInfo.cellY = cell[1];                                                                      
2370          }                                                                                                         
2371          if (span != null) {                                                                                       
2372              mPendingAddInfo.spanX = span[0];                                                                      
2373              mPendingAddInfo.spanY = span[1];                                                                      
2374          }                                                                                                         
2375                                                                                                                    
2376          AppWidgetHostView hostView = info.boundWidget;                                                            
2377          int appWidgetId;                                                                                          
2378          if (hostView != null) {                                                                                   
2379              appWidgetId = hostView.getAppWidgetId();                                                              
2380              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2381          } else {                                                                                                  
2382              // In this case, we either need to start an activity to get permission to bind                        
2383              // the widget, or we need to start an activity to configure the widget, or both.                      
2384              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2385              Bundle options = info.bindOptions;                                                                    
2386                                                                                                                    
2387              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2388                      appWidgetId, info.info, options);                                                             
2389              if (success) {                                                                                        
2390                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2391              } else {                                                                                              
2392                  mPendingAddWidgetInfo = info.info;                                                                
2393                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2394                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2395                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2396                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2397                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2398                  // TODO: we need to make sure that this accounts for the options bundle.                          
2399                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2400                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2401              }                                                                                                     
2402          }                                                                                                         
2403      }                                                                                                             
2404                                                                                                                    
2405      void processShortcut(Intent intent) {                                                                         
2406          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2407      }                                                                                                             
2408                                                                                                                    
2409      void processWallpaper(Intent intent) {                                                                        
2410          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2411      }                                                                                                             
2412                                                                                                                    
2413      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2414              int cellY) {                                                                                          
2415          final FolderInfo folderInfo = new FolderInfo();                                                           
2416          folderInfo.title = getText(R.string.folder_name);                                                         
2417                                                                                                                    
2418          // Update the model                                                                                       
2419          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2420                  false);                                                                                           


2421          sFolders.put(folderInfo.id, folderInfo);                                                                  
2422                                                                                                                    
2423          // Create the view                                                                                        
2424          FolderIcon newFolder =                                                                                    
2425              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2426          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2427                  isWorkspaceLocked());                                                                             
2428          // Force measure the new folder icon                                                                      
2429          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2430          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2431          return newFolder;                                                                                         
2432      }                                                                                                             
2433                                                                                                                    
2434      void removeFolder(FolderInfo folder) {                                                                        
2435          sFolders.remove(folder.id);                                                                               
2436      }                                                                                                             
2437                                                                                                                    
2438      protected ComponentName getWallpaperPickerComponent() {                                                       
2439          if (mLauncherCallbacks != null) {                                                                         
2440              return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2441          }                                                                                                         
2442          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2443      }                                                                                                             
2444                                                                                                                    
2445      /**                                                                                                           
2446       * Registers various content observers. The current implementation registers                                  
2447       * only a favorites observer to keep track of the favorites applications.                                     
2448       */                                                                                                           
2449      private void registerContentObservers() {                                                                     
2450          ContentResolver resolver = getContentResolver();                                                          
2451          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2452                  true, mWidgetObserver);                                                                           
2453      }                                                                                                             
2454                                                                                                                    
2455      @Override                                                                                                     
2456      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2457          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2458              switch (event.getKeyCode()) {                                                                         
2459                  case KeyEvent.KEYCODE_HOME:                                                                       
2460                      return true;                                                                                  
2461                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2462                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2463                          dumpState();                                                                              
2464                          return true;                                                                              
2465                      }                                                                                             
2466                      break;                                                                                        
2467              }                                                                                                     
2468          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2469              switch (event.getKeyCode()) {                                                                         
2470                  case KeyEvent.KEYCODE_HOME:                                                                       
2471                      return true;                                                                                  
2472              }                                                                                                     
2473          }                                                                                                         
2474                                                                                                                    
2475          return super.dispatchKeyEvent(event);                                                                     
2476      }                                                                                                             
2477                                                                                                                    
2478      @Override                                                                                                     
2479      public void onBackPressed() {                                                                                 
2480          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2481              return;                                                                                               
2482          }                                                                                                         
2483                                                                                                                    
2484          if (isAllAppsVisible()) {                                                                                 
2485              if (mAppsCustomizeContent.getContentType() ==                                                         
2486                      AppsCustomizePagedView.ContentType.Applications) {                                            
2487                  showWorkspace(true);                                                                              
2488              } else {                                                                                              
2489                  showOverviewMode(true);                                                                           
2490              }                                                                                                     










2491          } else if (mWorkspace.isInOverviewMode()) {                                                               
2492              mWorkspace.exitOverviewMode(true);                                                                    

2493          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2494              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2495              if (openFolder.isEditingName()) {                                                                     
2496                  openFolder.dismissEditingName();                                                                  
2497              } else {                                                                                              
2498                  closeFolder();                                                                                    
2499              }                                                                                                     
2500          } else {                                                                                                  
2501              mWorkspace.exitWidgetResizeMode();                                                                    
2502                                                                                                                    
2503              // Back button is a no-op here, but give at least some feedback for the button press                  
2504              mWorkspace.showOutlinesTemporarily();                                                                 
2505          }                                                                                                         
2506      }                                                                                                             
2507                                                                                                                    
2508      /**                                                                                                           
2509       * Re-listen when widgets are reset.                                                                          
2510       */                                                                                                           
2511      private void onAppWidgetReset() {                                                                             

2512          if (mAppWidgetHost != null) {                                                                             
2513              mAppWidgetHost.startListening();                                                                      
2514          }                                                                                                         
2515      }                                                                                                             
2516                                                                                                                    
2517      /**                                                                                                           
2518       * Launches the intent referred by the clicked shortcut.                                                      
2519       *                                                                                                            
2520       * @param v The view representing the clicked shortcut.                                                       
2521       */                                                                                                           
2522      public void onClick(View v) {                                                                                 
2523          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2524          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2525          if (v.getWindowToken() == null) {                                                                         
2526              return;                                                                                               
2527          }                                                                                                         
2528                                                                                                                    
2529          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2530              return;                                                                                               
2531          }                                                                                                         
2532                                                                                                                    
2533          if (v instanceof Workspace) {                                                                             
2534              if (mWorkspace.isInOverviewMode()) {                                                                  
2535                  mWorkspace.exitOverviewMode(true);                                                                

2536              }                                                                                                     
2537              return;                                                                                               
2538          }                                                                                                         
2539                                                                                                                    
2540          if (v instanceof CellLayout) {                                                                            
2541              if (mWorkspace.isInOverviewMode()) {                                                                  
2542                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    

2543              }                                                                                                     
2544          }                                                                                                         
2545                                                                                                                    
2546          Object tag = v.getTag();                                                                                  
2547          if (tag instanceof ShortcutInfo) {                                                                        
2548              onClickAppShortcut(v);                                                                                
2549          } else if (tag instanceof FolderInfo) {                                                                   
2550              if (v instanceof FolderIcon) {                                                                        
2551                  onClickFolderIcon(v);                                                                             
2552              }                                                                                                     
2553          } else if (v == mAllAppsButton) {                                                                         
2554              onClickAllAppsButton(v);                                                                              
2555          } else if (tag instanceof AppInfo) {                                                                      
2556              startAppShortcutOrInfoActivity(v);                                                                    
2557          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2558              if (v instanceof PendingAppWidgetHostView) {                                                          
2559                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2560              }                                                                                                     
2561          }                                                                                                         
2562      }                                                                                                             
2563                                                                                                                    
2564      public void onClickPagedViewIcon(View v) {                                                                    
2565          startAppShortcutOrInfoActivity(v);                                                                        
2566          if (mLauncherCallbacks != null) {                                                                         
2567              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2568          }                                                                                                         
2569      }                                                                                                             
2570                                                                                                                    

2571      public boolean onTouch(View v, MotionEvent event) {                                                           
2572          return false;                                                                                             
2573      }                                                                                                             
2574                                                                                                                    
2575      /**                                                                                                           
2576       * Event handler for the app widget view which has not fully restored.                                        
2577       */                                                                                                           
2578      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2579          if (mIsSafeModeEnabled) {                                                                                 
2580              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2581              return;                                                                                               
2582          }                                                                                                         
2583                                                                                                                    
2584          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2585          if (v.isReadyForClickSetup()) {                                                                           
2586              int widgetId = info.appWidgetId;                                                                      
2587              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2588              if (appWidgetInfo != null) {                                                                          
2589                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2590                          this, appWidgetInfo);                                                                     
2591                  mPendingAddInfo.copyFrom(info);                                                                   
2592                  mPendingAddWidgetId = widgetId;                                                                   
2593                                                                                                                    
2594                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2595                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2596              }                                                                                                     
2597          } else if (info.installProgress < 0) {                                                                    
2598              // The install has not been queued                                                                    
2599              final String packageName = info.providerName.getPackageName();                                        
2600              showBrokenAppInstallDialog(packageName,                                                               
2601                  new DialogInterface.OnClickListener() {                                                           
2602                      public void onClick(DialogInterface dialog, int id) {                                         
2603                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2604                      }                                                                                             
2605                  });                                                                                               
2606          } else {                                                                                                  
2607              // Download has started.                                                                              
2608              final String packageName = info.providerName.getPackageName();                                        
2609              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2610          }                                                                                                         
2611      }                                                                                                             
2612                                                                                                                    
2613      /**                                                                                                           
2614       * Event handler for the "grid" button that appears on the home screen, which                                 
2615       * enters all apps mode.                                                                                      
2616       *                                                                                                            
2617       * @param v The view that was clicked.                                                                        
2618       */                                                                                                           
2619      protected void onClickAllAppsButton(View v) {                                                                 
2620          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2621          if (isAllAppsVisible()) {                                                                                 

2622              showWorkspace(true);                                                                                  
2623          } else {                                                                                                  
2624              showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2625          }                                                                                                         
2626          if (mLauncherCallbacks != null) {                                                                         
2627              mLauncherCallbacks.onClickAllAppsButton(v);                                                           



2628          }                                                                                                         
2629      }                                                                                                             
2630                                                                                                                    
2631      private void showBrokenAppInstallDialog(final String packageName,                                             
2632              DialogInterface.OnClickListener onSearchClickListener) {                                              
2633          new AlertDialog.Builder(this)                                                                             
2634              .setTitle(R.string.abandoned_promises_title)                                                          
2635              .setMessage(R.string.abandoned_promise_explanation)                                                   
2636              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2637              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2638                  new DialogInterface.OnClickListener() {                                                           
2639                      public void onClick(DialogInterface dialog, int id) {                                         
2640                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2641                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2642                      }                                                                                             
2643                  })                                                                                                
2644              .create().show();                                                                                     
2645          return;                                                                                                   
2646      }                                                                                                             
2647                                                                                                                    
2648      /**                                                                                                           
2649       * Event handler for an app shortcut click.                                                                   
2650       *                                                                                                            
2651       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2652       */                                                                                                           
2653      protected void onClickAppShortcut(final View v) {                                                             
2654          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2655          Object tag = v.getTag();                                                                                  
2656          if (!(tag instanceof ShortcutInfo)) {                                                                     
2657              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2658          }                                                                                                         
2659                                                                                                                    
2660          // Open shortcut                                                                                          
2661          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2662                                                                                                                    
2663          if (shortcut.isDisabled != 0) {                                                                           
2664              int error = R.string.activity_not_available;                                                          
2665              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2666                  error = R.string.safemode_shortcut_error;                                                         
2667              }                                                                                                     
2668              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2669              return;                                                                                               
2670          }                                                                                                         
2671                                                                                                                    
2672          final Intent intent = shortcut.intent;                                                                    
2673                                                                                                                    
2674          // Check for special shortcuts                                                                            
2675          if (intent.getComponent() != null) {                                                                      
2676              final String shortcutClass = intent.getComponent().getClassName();                                    
2677                                                                                                                    
2678              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2679                  MemoryDumpActivity.startDump(this);                                                               
2680                  return;                                                                                           
2681              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2682                  toggleShowWeightWatcher();                                                                        
2683                  return;                                                                                           
2684              }                                                                                                     
2685          }                                                                                                         
2686                                                                                                                    
2687          // Check for abandoned promise                                                                            
2688          if ((v instanceof BubbleTextView)                                                                         
2689                  && shortcut.isPromise()                                                                           
2690                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2691              showBrokenAppInstallDialog(                                                                           
2692                      shortcut.getTargetComponent().getPackageName(),                                               
2693                      new DialogInterface.OnClickListener() {                                                       
2694                          public void onClick(DialogInterface dialog, int id) {                                     
2695                              startAppShortcutOrInfoActivity(v);                                                    
2696                          }                                                                                         
2697                      });                                                                                           
2698              return;                                                                                               
2699          }                                                                                                         
2700                                                                                                                    
2701          // Start activities                                                                                       
2702          startAppShortcutOrInfoActivity(v);                                                                        
2703                                                                                                                    
2704          if (mLauncherCallbacks != null) {                                                                         
2705              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2706          }                                                                                                         
2707      }                                                                                                             
2708                                                                                                                    
2709      private void startAppShortcutOrInfoActivity(View v) {                                                         

2710          Object tag = v.getTag();                                                                                  
2711          final ShortcutInfo shortcut;                                                                              
2712          final Intent intent;                                                                                      
2713          if (tag instanceof ShortcutInfo) {                                                                        
2714              shortcut = (ShortcutInfo) tag;                                                                        
2715              intent = shortcut.intent;                                                                             
2716              int[] pos = new int[2];                                                                               
2717              v.getLocationOnScreen(pos);                                                                           
2718              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2719                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2720                                                                                                                    
2721          } else if (tag instanceof AppInfo) {                                                                      
2722              shortcut = null;                                                                                      
2723              intent = ((AppInfo) tag).intent;                                                                      
2724          } else {                                                                                                  
2725              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2726          }                                                                                                         
2727                                                                                                                    
2728          boolean success = startActivitySafely(v, intent, tag);                                                    
2729          mStats.recordLaunch(intent, shortcut);                                                                    
2730                                                                                                                    
2731          if (success && v instanceof BubbleTextView) {                                                             
2732              mWaitingForResume = (BubbleTextView) v;                                                               
2733              mWaitingForResume.setStayPressed(true);                                                               
2734          }                                                                                                         
2735      }                                                                                                             
2736                                                                                                                    
2737      /**                                                                                                           
2738       * Event handler for a folder icon click.                                                                     
2739       *                                                                                                            
2740       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2741       */                                                                                                           
2742      protected void onClickFolderIcon(View v) {                                                                    
2743          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2744          if (!(v instanceof FolderIcon)){                                                                          
2745              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2746          }                                                                                                         
2747                                                                                                                    
2748          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2749          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2750          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2751                                                                                                                    
2752          // If the folder info reports that the associated folder is open, then verify that                        
2753          // it is actually opened. There have been a few instances where this gets out of sync.                    
2754          if (info.opened && openFolder == null) {                                                                  
2755              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2756                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2757              info.opened = false;                                                                                  
2758          }                                                                                                         
2759                                                                                                                    
2760          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2761              // Close any open folder                                                                              
2762              closeFolder();                                                                                        
2763              // Open the requested folder                                                                          
2764              openFolder(folderIcon);                                                                               
2765          } else {                                                                                                  
2766              // Find the open folder...                                                                            
2767              int folderScreen;                                                                                     
2768              if (openFolder != null) {                                                                             
2769                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2770                  // .. and close it                                                                                
2771                  closeFolder(openFolder);                                                                          
2772                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2773                      // Close any folder open on the current screen                                                
2774                      closeFolder();                                                                                
2775                      // Pull the folder onto this screen                                                           
2776                      openFolder(folderIcon);                                                                       
2777                  }                                                                                                 
2778              }                                                                                                     
2779          }                                                                                                         
2780                                                                                                                    
2781          if (mLauncherCallbacks != null) {                                                                         
2782              mLauncherCallbacks.onClickFolderIcon(v);                                                              
2783          }                                                                                                         
2784      }                                                                                                             
2785                                                                                                                    
2786      /**                                                                                                           
2787       * Event handler for the (Add) Widgets button that appears after a long press                                 
2788       * on the home screen.                                                                                        
2789       */                                                                                                           
2790      protected void onClickAddWidgetButton(View view) {                                                            
2791          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2792          if (mIsSafeModeEnabled) {                                                                                 
2793              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2794          } else {                                                                                                  
2795              showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  

2796              if (mLauncherCallbacks != null) {                                                                     
2797                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
2798              }                                                                                                     
2799          }                                                                                                         
2800      }                                                                                                             
2801                                                                                                                    
2802      /**                                                                                                           
2803       * Event handler for the wallpaper picker button that appears after a long press                              
2804       * on the home screen.                                                                                        
2805       */                                                                                                           
2806      protected void onClickWallpaperPicker(View v) {                                                               
2807          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2808          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2809          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2810          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            


2811                                                                                                                    
2812          if (mLauncherCallbacks != null) {                                                                         
2813              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
2814          }                                                                                                         
2815      }                                                                                                             
2816                                                                                                                    
2817      /**                                                                                                           
2818       * Event handler for a click on the settings button that appears after a long press                           
2819       * on the home screen.                                                                                        
2820       */                                                                                                           
2821      protected void onClickSettingsButton(View v) {                                                                
2822          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2823          if (mLauncherCallbacks != null) {                                                                         
2824              mLauncherCallbacks.onClickSettingsButton(v);                                                          
2825          }                                                                                                         
2826      }                                                                                                             
2827                                                                                                                    
2828      public void onTouchDownAllAppsButton(View v) {                                                                
2829          // Provide the same haptic feedback that the system offers for virtual keys.                              
2830          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2831      }                                                                                                             
2832                                                                                                                    
2833      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2834          // Provide the same haptic feedback that the system offers for virtual keys.                              
2835          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2836      }                                                                                                             
2837                                                                                                                    
2838      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2839          if (mHapticFeedbackTouchListener == null) {                                                               
2840              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           

2841                  @Override                                                                                         
2842                  public boolean onTouch(View v, MotionEvent event) {                                               
2843                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2844                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2845                      }                                                                                             
2846                      return false;                                                                                 
2847                  }                                                                                                 
2848              };                                                                                                    
2849          }                                                                                                         
2850          return mHapticFeedbackTouchListener;                                                                      
2851      }                                                                                                             
2852                                                                                                                    
2853      public void onDragStarted(View view) {                                                                        
2854          if (isOnCustomContent()) {                                                                                
2855              // Custom content screen doesn't participate in drag and drop. If on custom                           
2856              // content screen, move to default.                                                                   
2857              moveWorkspaceToDefaultScreen();                                                                       
2858          }                                                                                                         
2859                                                                                                                    
2860          if (mLauncherCallbacks != null) {                                                                         
2861              mLauncherCallbacks.onDragStarted(view);                                                               
2862          }                                                                                                         
2863      }                                                                                                             
2864                                                                                                                    
2865      /**                                                                                                           
2866       * Called when the user stops interacting with the launcher.                                                  
2867       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2868       */                                                                                                           
2869      protected void onInteractionEnd() {                                                                           
2870          if (mLauncherCallbacks != null) {                                                                         
2871              mLauncherCallbacks.onInteractionEnd();                                                                
2872          }                                                                                                         
2873      }                                                                                                             
2874                                                                                                                    
2875      /**                                                                                                           
2876       * Called when the user starts interacting with the launcher.                                                 
2877       * The possible interactions are:                                                                             
2878       *  - open all apps                                                                                           
2879       *  - reorder an app shortcut, or a widget                                                                    
2880       *  - open the overview mode.                                                                                 
2881       * This is a good time to stop doing things that only make sense                                              
2882       * when the user is on the homescreen and not doing housekeeping.                                             
2883       */                                                                                                           
2884      protected void onInteractionBegin() {                                                                         
2885          if (mLauncherCallbacks != null) {                                                                         
2886              mLauncherCallbacks.onInteractionBegin();                                                              






















2887          }                                                                                                         
2888      }                                                                                                             
2889                                                                                                                    
2890      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2891          try {                                                                                                     
2892              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2893              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2894          } catch (SecurityException e) {                                                                           
2895              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2896              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2897          } catch (ActivityNotFoundException e) {                                                                   
2898              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2899              Log.e(TAG, "Unable to launch settings");                                                              
2900          }                                                                                                         
2901      }                                                                                                             
2902                                                                                                                    
2903      // returns true if the activity was started                                                                   
2904      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2905              UserHandleCompat user) {                                                                              
2906          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2907              // System applications cannot be installed. For now, show a toast explaining that.                    
2908              // We may give them the option of disabling apps this way.                                            
2909              int messageId = R.string.uninstall_system_app_text;                                                   
2910              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2911              return false;                                                                                         
2912          } else {                                                                                                  
2913              String packageName = componentName.getPackageName();                                                  
2914              String className = componentName.getClassName();                                                      
2915              Intent intent = new Intent(                                                                           
2916                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2917              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2918                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2919              if (user != null) {                                                                                   
2920                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2921              }                                                                                                     
2922              startActivity(intent);                                                                                
2923              return true;                                                                                          
2924          }                                                                                                         
2925      }                                                                                                             
2926                                                                                                                    
2927      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2928          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2929          try {                                                                                                     
2930              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2931              // private contract between launcher and may be ignored in the future).                               
2932              boolean useLaunchAnimation = (v != null) &&                                                           
2933                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2934              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2935              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2936                                                                                                                    
2937              UserHandleCompat user = null;                                                                         
2938              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2939                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2940                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2941              }                                                                                                     
2942                                                                                                                    
2943              Bundle optsBundle = null;                                                                             
2944              if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                                
2945                  // On pre-L devices, we use the scale up transition.                                              
2946 -                // Otherwise we use system default.                                                               
2947                  ActivityOptions opts =                                                                            
2948                          ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
2949 +                optsBundle = opts.toBundle();                                                                     
2950 +            } else if (useLaunchAnimation && Utilities.isLmpMr1()) {                                              
2951 +                // On L-MR1 devices, we use custom slide up animation without a delay                             
2952 +                // On L devices, we use the system default slide up.                                              
2953 +                ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,                                  
2954 +                        R.anim.task_open_enter, R.anim.no_anim);                                                  
2955                  optsBundle = opts.toBundle();                                                                     

































2956              }                                                                                                     
2957                                                                                                                    
2958              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
2959                  // Could be launching some bookkeeping activity                                                   
2960                  startActivity(intent, optsBundle);                                                                
2961              } else {                                                                                              
2962                  // TODO Component can be null when shortcuts are supported for secondary user                     
2963                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
2964                          intent.getSourceBounds(), optsBundle);                                                    
2965              }                                                                                                     
2966              return true;                                                                                          
2967          } catch (SecurityException e) {                                                                           
2968              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2969              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
2970                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
2971                      "or use the exported attribute for this activity. "                                           
2972                      + "tag="+ tag + " intent=" + intent, e);                                                      
2973          }                                                                                                         
2974          return false;                                                                                             
2975      }                                                                                                             
2976                                                                                                                    
2977      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
2978          boolean success = false;                                                                                  
2979          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
2980              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
2981              return false;                                                                                         
2982          }                                                                                                         
2983          try {                                                                                                     
2984              success = startActivity(v, intent, tag);                                                              
2985          } catch (ActivityNotFoundException e) {                                                                   
2986              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2987              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
2988          }                                                                                                         
2989          return success;                                                                                           
2990      }                                                                                                             
2991                                                                                                                    
2992      /**                                                                                                           
2993       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
2994       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
2995       */                                                                                                           
2996      private void copyFolderIconToImage(FolderIcon fi) {                                                           
2997          final int width = fi.getMeasuredWidth();                                                                  
2998          final int height = fi.getMeasuredHeight();                                                                
2999                                                                                                                    
3000          // Lazy load ImageView, Bitmap and Canvas                                                                 
3001          if (mFolderIconImageView == null) {                                                                       
3002              mFolderIconImageView = new ImageView(this);                                                           
3003          }                                                                                                         
3004          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3005                  mFolderIconBitmap.getHeight() != height) {                                                        
3006              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3007              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3008          }                                                                                                         
3009                                                                                                                    
3010          DragLayer.LayoutParams lp;                                                                                
3011          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3012              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3013          } else {                                                                                                  
3014              lp = new DragLayer.LayoutParams(width, height);                                                       
3015          }                                                                                                         
3016                                                                                                                    
3017          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3018          // view size by this scale factor.                                                                        
3019          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3020          lp.customPosition = true;                                                                                 
3021          lp.x = mRectForFolderAnimation.left;                                                                      
3022          lp.y = mRectForFolderAnimation.top;                                                                       
3023          lp.width = (int) (scale * width);                                                                         
3024          lp.height = (int) (scale * height);                                                                       
3025                                                                                                                    
3026          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3027          fi.draw(mFolderIconCanvas);                                                                               
3028          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3029          if (fi.getFolder() != null) {                                                                             
3030              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3031              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3032          }                                                                                                         
3033          // Just in case this image view is still in the drag layer from a previous animation,                     
3034          // we remove it and re-add it.                                                                            
3035          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3036              mDragLayer.removeView(mFolderIconImageView);                                                          
3037          }                                                                                                         
3038          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3039          if (fi.getFolder() != null) {                                                                             
3040              fi.getFolder().bringToFront();                                                                        
3041          }                                                                                                         
3042      }                                                                                                             
3043                                                                                                                    
3044      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3045          if (fi == null) return;                                                                                   
3046          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3047          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3048          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3049                                                                                                                    
3050          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3051          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3052              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3053              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3054              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3055          }                                                                                                         
3056                                                                                                                    
3057          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3058          copyFolderIconToImage(fi);                                                                                
3059          fi.setVisibility(View.INVISIBLE);                                                                         
3060                                                                                                                    
3061          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3062                  scaleX, scaleY);                                                                                  
3063          if (Utilities.isLmpOrAbove()) {                                                                           
3064              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3065          }                                                                                                         
3066          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3067          oa.start();                                                                                               
3068      }                                                                                                             
3069                                                                                                                    
3070      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3071          if (fi == null) return;                                                                                   
3072          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3073          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3074          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3075                                                                                                                    
3076          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3077                                                                                                                    
3078          // We remove and re-draw the FolderIcon in-case it has changed                                            
3079          mDragLayer.removeView(mFolderIconImageView);                                                              
3080          copyFolderIconToImage(fi);                                                                                
3081          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3082                  scaleX, scaleY);                                                                                  
3083          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3084          oa.addListener(new AnimatorListenerAdapter() {                                                            
3085              @Override                                                                                             
3086              public void onAnimationEnd(Animator animation) {                                                      
3087                  if (cl != null) {                                                                                 
3088                      cl.clearFolderLeaveBehind();                                                                  
3089                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3090                      mDragLayer.removeView(mFolderIconImageView);                                                  
3091                      fi.setVisibility(View.VISIBLE);                                                               
3092                  }                                                                                                 
3093              }                                                                                                     
3094          });                                                                                                       
3095          oa.start();                                                                                               
3096      }                                                                                                             
3097                                                                                                                    
3098      /**                                                                                                           
3099       * Opens the user folder described by the specified tag. The opening of the folder                            
3100       * is animated relative to the specified View. If the View is null, no animation                              
3101       * is played.                                                                                                 
3102       *                                                                                                            
3103       * @param folderInfo The FolderInfo describing the folder to open.                                            
3104       */                                                                                                           
3105      public void openFolder(FolderIcon folderIcon) {                                                               
3106          Folder folder = folderIcon.getFolder();                                                                   






3107          FolderInfo info = folder.mInfo;                                                                           
3108                                                                                                                    
3109          info.opened = true;                                                                                       



3110                                                                                                                    
3111          // Just verify that the folder hasn't already been added to the DragLayer.                                
3112          // There was a one-off crash where the folder had a parent already.                                       
3113          if (folder.getParent() == null) {                                                                         
3114              mDragLayer.addView(folder);                                                                           
3115              mDragController.addDropTarget((DropTarget) folder);                                                   
3116          } else {                                                                                                  
3117              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3118                      folder.getParent() + ").");                                                                   
3119          }                                                                                                         
3120          folder.animateOpen();                                                                                     
3121          growAndFadeOutFolderIcon(folderIcon);                                                                     
3122                                                                                                                    
3123          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3124          // the workspace items                                                                                    
3125          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3126          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3127      }                                                                                                             
3128                                                                                                                    
3129      public void closeFolder() {                                                                                   
3130          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3131          if (folder != null) {                                                                                     
3132              if (folder.isEditingName()) {                                                                         
3133                  folder.dismissEditingName();                                                                      
3134              }                                                                                                     
3135              closeFolder(folder);                                                                                  
3136          }                                                                                                         
3137      }                                                                                                             
3138                                                                                                                    
3139      void closeFolder(Folder folder) {                                                                             

3140          folder.getInfo().opened = false;                                                                          
3141                                                                                                                    
3142          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3143          if (parent != null) {                                                                                     
3144              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3145              shrinkAndFadeInFolderIcon(fi);                                                                        



3146          }                                                                                                         
3147          folder.animateClosed();                                                                                   
3148                                                                                                                    
3149          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3150          // longer occludeds the workspace items                                                                   
3151          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3152      }                                                                                                             
3153                                                                                                                    
3154      public boolean onLongClick(View v) {                                                                          
3155          if (!isDraggingEnabled()) return false;                                                                   
3156          if (isWorkspaceLocked()) return false;                                                                    
3157          if (mState != State.WORKSPACE) return false;                                                              
3158                                                                                                                    
3159          if (v instanceof Workspace) {                                                                             
3160              if (!mWorkspace.isInOverviewMode()) {                                                                 
3161                  if (mWorkspace.enterOverviewMode()) {                                                             


3162                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3163                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3164                      return true;                                                                                  
3165                  } else {                                                                                          
3166                      return false;                                                                                 
3167                  }                                                                                                 
3168              } else {                                                                                              
3169                  return false;                                                                                     
3170              }                                                                                                     
3171          }                                                                                                         
3172                                                                                                                    
3173          CellLayout.CellInfo longClickCellInfo = null;                                                             
3174          View itemUnderLongClick = null;                                                                           
3175          if (v.getTag() instanceof ItemInfo) {                                                                     
3176              ItemInfo info = (ItemInfo) v.getTag();                                                                
3177              longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                

3178              itemUnderLongClick = longClickCellInfo.cell;                                                          
3179              resetAddInfo();                                                                                       
3180          }                                                                                                         
3181                                                                                                                    
3182          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3183          // on hotseat items.                                                                                      
3184          final boolean inHotseat = isHotseatLayout(v);                                                             
3185          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3186          if (allowLongPress && !mDragController.isDragging()) {                                                    

3187              if (itemUnderLongClick == null) {                                                                     
3188                  // User long pressed on empty space                                                               
3189                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3190                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3191                  if (mWorkspace.isInOverviewMode()) {                                                              
3192                      mWorkspace.startReordering(v);                                                                
3193                  } else {                                                                                          
3194                      mWorkspace.enterOverviewMode();                                                               

3195                  }                                                                                                 
3196              } else {                                                                                              
3197                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3198                          mHotseat.getOrderInHotseat(                                                               
3199                                  longClickCellInfo.cellX,                                                          
3200                                  longClickCellInfo.cellY));                                                        
3201                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3202                      // User long pressed on an item                                                               
3203                      mWorkspace.startDrag(longClickCellInfo);                                                      
3204                  }                                                                                                 
3205              }                                                                                                     
3206          }                                                                                                         
3207          return true;                                                                                              
3208      }                                                                                                             
3209                                                                                                                    
3210      boolean isHotseatLayout(View layout) {                                                                        
3211          return mHotseat != null && layout != null &&                                                              
3212                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3213      }                                                                                                             
3214                                                                                                                    
3215      /**                                                                                                           
3216       * Returns the CellLayout of the specified container at the specified screen.                                 
3217       */                                                                                                           
3218      CellLayout getCellLayout(long container, long screenId) {                                                     

3219          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3220              if (mHotseat != null) {                                                                               
3221                  return mHotseat.getLayout();                                                                      
3222              } else {                                                                                              
3223                  return null;                                                                                      
3224              }                                                                                                     
3225          } else {                                                                                                  
3226              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3227          }                                                                                                         
3228      }                                                                                                             
3229                                                                                                                    







3230      public boolean isAllAppsVisible() {                                                                           
3231          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3232      }                                                                                                             
3233                                                                                                                    
3234      private void setWorkspaceBackground(boolean workspace) {                                                      
3235          mLauncherView.setBackground(workspace ?                                                                   
3236                  mWorkspaceBackgroundDrawable : null);                                                             






















3237      }                                                                                                             
3238                                                                                                                    
3239      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3240          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3241          int curflags = getWindow().getAttributes().flags                                                          
3242                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3243          if (wpflags != curflags) {                                                                                
3244              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3245          }                                                                                                         
3246          setWorkspaceBackground(visible);                                                                          
3247      }                                                                                                             
3248                                                                                                                    
3249      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3250          if (v instanceof LauncherTransitionable) {                                                                
3251              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3252          }                                                                                                         
3253      }                                                                                                             
3254                                                                                                                    
3255      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3256          if (v instanceof LauncherTransitionable) {                                                                
3257              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3258          }                                                                                                         
3259                                                                                                                    
3260          // Update the workspace transition step as well                                                           
3261          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3262      }                                                                                                             
3263                                                                                                                    
3264      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3265          if (v instanceof LauncherTransitionable) {                                                                
3266              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3267          }                                                                                                         
3268      }                                                                                                             
3269                                                                                                                    
3270      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3271          if (v instanceof LauncherTransitionable) {                                                                
3272              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3273          }                                                                                                         
3274                                                                                                                    
3275          // Update the workspace transition step as well                                                           
3276          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3277      }                                                                                                             
3278                                                                                                                    
3279      /**                                                                                                           
3280       * Things to test when changing the following seven functions.                                                
3281       *   - Home from workspace                                                                                    
3282       *          - from center screen                                                                              
3283       *          - from other screens                                                                              
3284       *   - Home from all apps                                                                                     
3285       *          - from center screen                                                                              
3286       *          - from other screens                                                                              
3287       *   - Back from all apps                                                                                     
3288       *          - from center screen                                                                              
3289       *          - from other screens                                                                              
3290       *   - Launch app from workspace and quit                                                                     
3291       *          - with back                                                                                       
3292       *          - with home                                                                                       
3293       *   - Launch app from all apps and quit                                                                      
3294       *          - with back                                                                                       
3295       *          - with home                                                                                       
3296       *   - Go to a screen that's not the default, then all                                                        
3297       *     apps, and launch and app, and go back                                                                  
3298       *          - with back                                                                                       
3299       *          -with home                                                                                        
3300       *   - On workspace, long press power and go back                                                             
3301       *          - with back                                                                                       
3302       *          - with home                                                                                       
3303       *   - On all apps, long press power and go back                                                              
3304       *          - with back                                                                                       
3305       *          - with home                                                                                       
3306       *   - On workspace, power off                                                                                
3307       *   - On all apps, power off                                                                                 
3308       *   - Launch an app and turn off the screen while in that app                                                
3309       *          - Go back with home key                                                                           
3310       *          - Go back with back key  TODO: make this not go to workspace                                      
3311       *          - From all apps                                                                                   
3312       *          - From workspace                                                                                  
3313       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3314       *          - From all apps                                                                                   
3315       *          - From the center workspace                                                                       
3316       *          - From another workspace                                                                          
3317       */                                                                                                           
3318                                                                                                                    
3319      /**                                                                                                           
3320       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3321       * Assumes that the view to show is anchored at either the very top or very bottom                            
3322       * of the screen.                                                                                             
3323       */                                                                                                           
3324      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3325          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3326          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3327      }                                                                                                             
3328                                                                                                                    
3329      @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3330      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3331                                           final AppsCustomizePagedView.ContentType contentType) {                  
3332          if (mStateAnimation != null) {                                                                            
3333              mStateAnimation.setDuration(0);                                                                       
3334              mStateAnimation.cancel();                                                                             
3335              mStateAnimation = null;                                                                               
3336          }                                                                                                         
3337                                                                                                                    
3338          boolean material = Utilities.isLmpOrAbove();                                                              
3339                                                                                                                    
3340          final Resources res = getResources();                                                                     
3341                                                                                                                    
3342          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3343          final int itemsAlphaStagger =                                                                             
3344                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3345                                                                                                                    
3346          final View fromView = mWorkspace;                                                                         
3347          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3348                                                                                                                    
3349          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3350                                                                                                                    
3351          Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3352                  Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3353          Animator workspaceAnim =                                                                                  
3354                  mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3355          if (!LauncherAppState.isDisableAllApps()                                                                  
3356                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3357              // Set the content type for the all apps/widgets space                                                
3358              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3359          }                                                                                                         
3360                                                                                                                    
3361          // If for some reason our views aren't initialized, don't animate                                         
3362          boolean initialized = getAllAppsButton() != null;                                                         
3363                                                                                                                    
3364          if (animated && initialized) {                                                                            
3365              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3366              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3367                      toView.findViewById(R.id.apps_customize_pane_content);                                        
3368                                                                                                                    
3369              final View page = content.getPageAt(content.getCurrentPage());                                        
3370              final View revealView = toView.findViewById(R.id.fake_page);                                          
3371                                                                                                                    
3372              final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3373              if (isWidgetTray) {                                                                                   
3374                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3375              } else {                                                                                              
3376                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3377              }                                                                                                     
3378                                                                                                                    
3379              // Hide the real page background, and swap in the fake one                                            
3380              content.setPageBackgroundsVisible(false);                                                             
3381              revealView.setVisibility(View.VISIBLE);                                                               
3382              // We need to hide this view as the animation start will be posted.                                   
3383              revealView.setAlpha(0);                                                                               
3384                                                                                                                    
3385              int width = revealView.getMeasuredWidth();                                                            
3386              int height = revealView.getMeasuredHeight();                                                          
3387              float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3388                                                                                                                    
3389              revealView.setTranslationY(0);                                                                        
3390              revealView.setTranslationX(0);                                                                        
3391                                                                                                                    
3392              // Get the y delta between the center of the page and the center of the all apps button               
3393              int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3394                      getAllAppsButton(), null);                                                                    
3395                                                                                                                    
3396              float alpha = 0;                                                                                      
3397              float xDrift = 0;                                                                                     
3398              float yDrift = 0;                                                                                     
3399              if (material) {                                                                                       
3400                  alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3401                  yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3402                  xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3403              } else {                                                                                              
3404                  yDrift = 2 * height / 3;                                                                          
3405                  xDrift = 0;                                                                                       
3406              }                                                                                                     
3407              final float initAlpha = alpha;                                                                        
3408                                                                                                                    
3409              layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3410              PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3411              PropertyValuesHolder panelDriftY =                                                                    
3412                      PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3413              PropertyValuesHolder panelDriftX =                                                                    
3414                      PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3415                                                                                                                    
3416              ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3417                      panelAlpha, panelDriftY, panelDriftX);                                                        
3418                                                                                                                    
3419              panelAlphaAndDrift.setDuration(revealDuration);                                                       
3420              panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3421                                                                                                                    
3422              mStateAnimation.play(panelAlphaAndDrift);                                                             
3423                                                                                                                    
3424              if (page != null) {                                                                                   
3425                  page.setVisibility(View.VISIBLE);                                                                 
3426                  layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3427                                                                                                                    
3428                  ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3429                  page.setTranslationY(yDrift);                                                                     
3430                  pageDrift.setDuration(revealDuration);                                                            
3431                  pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3432                  pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3433                  mStateAnimation.play(pageDrift);                                                                  
3434                                                                                                                    
3435                  page.setAlpha(0f);                                                                                
3436                  ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3437                  itemsAlpha.setDuration(revealDuration);                                                           
3438                  itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3439                  itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3440                  mStateAnimation.play(itemsAlpha);                                                                 
3441              }                                                                                                     
3442                                                                                                                    
3443              View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3444              pageIndicators.setAlpha(0.01f);                                                                       
3445              ObjectAnimator indicatorsAlpha =                                                                      
3446                      ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3447              indicatorsAlpha.setDuration(revealDuration);                                                          
3448              mStateAnimation.play(indicatorsAlpha);                                                                
3449                                                                                                                    
3450              if (material) {                                                                                       
3451                  final View allApps = getAllAppsButton();                                                          
3452                  int allAppsButtonSize = LauncherAppState.getInstance().                                           
3453                          getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3454                  float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3455                  Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3456                                  height / 2, startRadius, revealRadius);                                           
3457                  reveal.setDuration(revealDuration);                                                               
3458                  reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3459                                                                                                                    
3460                  reveal.addListener(new AnimatorListenerAdapter() {                                                
3461                      public void onAnimationStart(Animator animation) {                                            
3462                          if (!isWidgetTray) {                                                                      
3463                              allApps.setVisibility(View.INVISIBLE);                                                
3464                          }                                                                                         
3465                      }                                                                                             
3466                      public void onAnimationEnd(Animator animation) {                                              
3467                          if (!isWidgetTray) {                                                                      
3468                              allApps.setVisibility(View.VISIBLE);                                                  
3469                          }                                                                                         
3470                      }                                                                                             
3471                  });                                                                                               
3472                  mStateAnimation.play(reveal);                                                                     
3473              }                                                                                                     
3474                                                                                                                    
3475              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3476                  @Override                                                                                         
3477                  public void onAnimationEnd(Animator animation) {                                                  
3478                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3479                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3480                                                                                                                    
3481                      revealView.setVisibility(View.INVISIBLE);                                                     
3482                                                                                                                    
3483                      for (View v : layerViews.keySet()) {                                                          
3484                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3485                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3486                          }                                                                                         
3487                      }                                                                                             
3488                      content.setPageBackgroundsVisible(true);                                                      
3489                                                                                                                    
3490                      // Hide the search bar                                                                        
3491                      if (mSearchDropTargetBar != null) {                                                           
3492                          mSearchDropTargetBar.hideSearchBar(false);                                                
3493                      }                                                                                             
3494                                                                                                                    
3495                      // This can hold unnecessary references to views.                                             
3496                      mStateAnimation = null;                                                                       
3497                  }                                                                                                 
3498                                                                                                                    
3499              });                                                                                                   
3500                                                                                                                    
3501              if (workspaceAnim != null) {                                                                          
3502                  mStateAnimation.play(workspaceAnim);                                                              
3503              }                                                                                                     
3504                                                                                                                    
3505              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3506              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3507              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3508              final Runnable startAnimRunnable = new Runnable() {                                                   
3509                  public void run() {                                                                               
3510                      // Check that mStateAnimation hasn't changed while                                            
3511                      // we waited for a layout/draw pass                                                           
3512                      if (mStateAnimation != stateAnimation)                                                        
3513                          return;                                                                                   
3514                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3515                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3516                                                                                                                    
3517                      revealView.setAlpha(initAlpha);                                                               
3518                                                                                                                    
3519                      for (View v : layerViews.keySet()) {                                                          
3520                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3521                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3522                          }                                                                                         
3523                      }                                                                                             
3524                                                                                                                    
3525                      if (Utilities.isLmpOrAbove()) {                                                               
3526                          for (View v : layerViews.keySet()) {                                                      
3527                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3528                          }                                                                                         
3529                      }                                                                                             
3530                      mStateAnimation.start();                                                                      
3531                  }                                                                                                 
3532              };                                                                                                    
3533              toView.bringToFront();                                                                                
3534              toView.setVisibility(View.VISIBLE);                                                                   
3535              toView.post(startAnimRunnable);                                                                       
3536          } else {                                                                                                  
3537              toView.setTranslationX(0.0f);                                                                         
3538              toView.setTranslationY(0.0f);                                                                         
3539              toView.setScaleX(1.0f);                                                                               
3540              toView.setScaleY(1.0f);                                                                               
3541              toView.setVisibility(View.VISIBLE);                                                                   
3542              toView.bringToFront();                                                                                
3543                                                                                                                    
3544              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3545                  // Hide the search bar                                                                            
3546                  if (mSearchDropTargetBar != null) {                                                               
3547                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3548                  }                                                                                                 
3549              }                                                                                                     
3550              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3551              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3552              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3553              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3554              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3555              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3556          }                                                                                                         
3557      }                                                                                                             
3558                                                                                                                    
3559      /**                                                                                                           
3560       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3561       * This is the opposite of showAppsCustomizeHelper.                                                           
3562       * @param animated If true, the transition will be animated.                                                  
3563       */                                                                                                           
3564      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3565              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3566                                                                                                                    
3567          if (mStateAnimation != null) {                                                                            
3568              mStateAnimation.setDuration(0);                                                                       
3569              mStateAnimation.cancel();                                                                             
3570              mStateAnimation = null;                                                                               
3571          }                                                                                                         
3572                                                                                                                    
3573          boolean material = Utilities.isLmpOrAbove();                                                              
3574          Resources res = getResources();                                                                           
3575                                                                                                                    
3576          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3577          final int itemsAlphaStagger =                                                                             
3578                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3579                                                                                                                    
3580          final View fromView = mAppsCustomizeTabHost;                                                              
3581          final View toView = mWorkspace;                                                                           
3582          Animator workspaceAnim = null;                                                                            
3583          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3584                                                                                                                    
3585          if (toState == Workspace.State.NORMAL) {                                                                  
3586              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3587                      toState, animated, layerViews);                                                               
3588          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3589                  toState == Workspace.State.OVERVIEW) {                                                            
3590              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3591                      toState, animated, layerViews);                                                               
3592          }                                                                                                         
3593                                                                                                                    
3594          // If for some reason our views aren't initialized, don't animate                                         
3595          boolean initialized = getAllAppsButton() != null;                                                         
3596                                                                                                                    
3597          if (animated && initialized) {                                                                            
3598              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3599              if (workspaceAnim != null) {                                                                          
3600                  mStateAnimation.play(workspaceAnim);                                                              
3601              }                                                                                                     
3602                                                                                                                    
3603              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3604                      fromView.findViewById(R.id.apps_customize_pane_content);                                      
3605                                                                                                                    
3606              final View page = content.getPageAt(content.getNextPage());                                           
3607                                                                                                                    
3608              // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3609              int count = content.getChildCount();                                                                  
3610              for (int i = 0; i < count; i++) {                                                                     
3611                  View child = content.getChildAt(i);                                                               
3612                  if (child != page) {                                                                              
3613                      child.setVisibility(View.INVISIBLE);                                                          
3614                  }                                                                                                 
3615              }                                                                                                     
3616              final View revealView = fromView.findViewById(R.id.fake_page);                                        
3617                                                                                                                    
3618              // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3619              // don't perform all these no-op animations. In particularly, this was causing                        
3620              // the all-apps button to pop in and out.                                                             
3621              if (fromView.getVisibility() == View.VISIBLE) {                                                       
3622                  AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3623                  final boolean isWidgetTray =                                                                      
3624                          contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3625                                                                                                                    
3626                  if (isWidgetTray) {                                                                               
3627                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3628                  } else {                                                                                          
3629                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3630                  }                                                                                                 
3631                                                                                                                    
3632                  int width = revealView.getMeasuredWidth();                                                        
3633                  int height = revealView.getMeasuredHeight();                                                      
3634                  float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3635                                                                                                                    
3636                  // Hide the real page background, and swap in the fake one                                        
3637                  revealView.setVisibility(View.VISIBLE);                                                           
3638                  content.setPageBackgroundsVisible(false);                                                         
3639                                                                                                                    
3640                  final View allAppsButton = getAllAppsButton();                                                    
3641                  revealView.setTranslationY(0);                                                                    
3642                  int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3643                          allAppsButton, null);                                                                     
3644                                                                                                                    
3645                  float xDrift = 0;                                                                                 
3646                  float yDrift = 0;                                                                                 
3647                  if (material) {                                                                                   
3648                      yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3649                      xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3650                  } else {                                                                                          
3651                      yDrift = 2 * height / 3;                                                                      
3652                      xDrift = 0;                                                                                   
3653                  }                                                                                                 
3654                                                                                                                    
3655                  layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
3656                  TimeInterpolator decelerateInterpolator = material ?                                              
3657                          new LogDecelerateInterpolator(100, 0) :                                                   
3658                          new DecelerateInterpolator(1f);                                                           
3659                                                                                                                    
3660                  // The vertical motion of the apps panel should be delayed by one frame                           
3661                  // from the conceal animation in order to give the right feel. We correpsondingly                 
3662                  // shorten the duration so that the slide and conceal end at the same time.                       
3663                  ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3664                          0, yDrift);                                                                               
3665                  panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3666                  panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3667                  panelDriftY.setInterpolator(decelerateInterpolator);                                              
3668                  mStateAnimation.play(panelDriftY);                                                                
3669                                                                                                                    
3670                  ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3671                          0, xDrift);                                                                               
3672                  panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3673                  panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3674                  panelDriftX.setInterpolator(decelerateInterpolator);                                              
3675                  mStateAnimation.play(panelDriftX);                                                                
3676                                                                                                                    
3677                  if (isWidgetTray || !material) {                                                                  
3678                      float finalAlpha = material ? 0.4f : 0f;                                                      
3679                      revealView.setAlpha(1f);                                                                      
3680                      ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3681                              1f, finalAlpha);                                                                      
3682                      panelAlpha.setDuration(material ? revealDuration : 150);                                      
3683                      panelAlpha.setInterpolator(decelerateInterpolator);                                           
3684                      panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
3685                      mStateAnimation.play(panelAlpha);                                                             
3686                  }                                                                                                 
3687                                                                                                                    
3688                  if (page != null) {                                                                               
3689                      layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
3690                                                                                                                    
3691                      ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3692                              0, yDrift);                                                                           
3693                      page.setTranslationY(0);                                                                      
3694                      pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3695                      pageDrift.setInterpolator(decelerateInterpolator);                                            
3696                      pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3697                      mStateAnimation.play(pageDrift);                                                              
3698                                                                                                                    
3699                      page.setAlpha(1f);                                                                            
3700                      ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3701                      itemsAlpha.setDuration(100);                                                                  
3702                      itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3703                      mStateAnimation.play(itemsAlpha);                                                             
3704                  }                                                                                                 
3705                                                                                                                    
3706                  View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3707                  pageIndicators.setAlpha(1f);                                                                      
3708                  ObjectAnimator indicatorsAlpha =                                                                  
3709                          LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3710                  indicatorsAlpha.setDuration(revealDuration);                                                      
3711                  indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3712                  mStateAnimation.play(indicatorsAlpha);                                                            
3713                                                                                                                    
3714                  width = revealView.getMeasuredWidth();                                                            
3715                                                                                                                    
3716                  if (material) {                                                                                   
3717                      if (!isWidgetTray) {                                                                          
3718                          allAppsButton.setVisibility(View.INVISIBLE);                                              
3719                      }                                                                                             
3720                      int allAppsButtonSize = LauncherAppState.getInstance().                                       
3721                              getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3722                      float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3723                      Animator reveal =                                                                             
3724                              LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3725                                      height / 2, revealRadius, finalRadius);                                       
3726                      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3727                      reveal.setDuration(revealDuration);                                                           
3728                      reveal.setStartDelay(itemsAlphaStagger);                                                      
3729                                                                                                                    
3730                      reveal.addListener(new AnimatorListenerAdapter() {                                            
3731                          public void onAnimationEnd(Animator animation) {                                          
3732                              revealView.setVisibility(View.INVISIBLE);                                             
3733                              if (!isWidgetTray) {                                                                  
3734                                  allAppsButton.setVisibility(View.VISIBLE);                                        
3735                              }                                                                                     
3736                          }                                                                                         
3737                      });                                                                                           
3738                                                                                                                    
3739                      mStateAnimation.play(reveal);                                                                 
3740                  }                                                                                                 
3741                                                                                                                    
3742                  dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3743                  dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3744                  mAppsCustomizeContent.stopScrolling();                                                            
3745              }                                                                                                     
3746                                                                                                                    
3747              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3748                  @Override                                                                                         
3749                  public void onAnimationEnd(Animator animation) {                                                  
3750                      fromView.setVisibility(View.GONE);                                                            
3751                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3752                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3753                      if (onCompleteRunnable != null) {                                                             
3754                          onCompleteRunnable.run();                                                                 
3755                      }                                                                                             
3756                                                                                                                    
3757                      for (View v : layerViews.keySet()) {                                                          
3758                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3759                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3760                          }                                                                                         
3761                      }                                                                                             
3762                                                                                                                    
3763                      content.setPageBackgroundsVisible(true);                                                      
3764                      // Unhide side pages                                                                          
3765                      int count = content.getChildCount();                                                          
3766                      for (int i = 0; i < count; i++) {                                                             
3767                          View child = content.getChildAt(i);                                                       
3768                          child.setVisibility(View.VISIBLE);                                                        
3769                      }                                                                                             
3770                                                                                                                    
3771                      // Reset page transforms                                                                      
3772                      if (page != null) {                                                                           
3773                          page.setTranslationX(0);                                                                  
3774                          page.setTranslationY(0);                                                                  
3775                          page.setAlpha(1);                                                                         
3776                      }                                                                                             
3777                      content.setCurrentPage(content.getNextPage());                                                
3778                                                                                                                    
3779                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
3780                                                                                                                    
3781                      // This can hold unnecessary references to views.                                             
3782                      mStateAnimation = null;                                                                       
3783                  }                                                                                                 
3784              });                                                                                                   
3785                                                                                                                    
3786              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3787              final Runnable startAnimRunnable = new Runnable() {                                                   
3788                  public void run() {                                                                               
3789                      // Check that mStateAnimation hasn't changed while                                            
3790                      // we waited for a layout/draw pass                                                           
3791                      if (mStateAnimation != stateAnimation)                                                        
3792                          return;                                                                                   
3793                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3794                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3795                                                                                                                    
3796                      for (View v : layerViews.keySet()) {                                                          
3797                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3798                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3799                          }                                                                                         
3800                      }                                                                                             
3801                                                                                                                    
3802                      if (Utilities.isLmpOrAbove()) {                                                               
3803                          for (View v : layerViews.keySet()) {                                                      
3804                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3805                          }                                                                                         
3806                      }                                                                                             
3807                      mStateAnimation.start();                                                                      
3808                  }                                                                                                 
3809              };                                                                                                    
3810              fromView.post(startAnimRunnable);                                                                     
3811          } else {                                                                                                  
3812              fromView.setVisibility(View.GONE);                                                                    
3813              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3814              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3815              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3816              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3817              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3818              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3819          }                                                                                                         

3820      }                                                                                                             
3821                                                                                                                    
3822      @Override                                                                                                     
3823      public void onTrimMemory(int level) {                                                                         
3824          super.onTrimMemory(level);                                                                                
3825          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
3826              // The widget preview db can result in holding onto over                                              
3827              // 3MB of memory for caching which isn't necessary.                                                   
3828              SQLiteDatabase.releaseMemory();                                                                       
3829                                                                                                                    
3830              // This clears all widget bitmaps from the widget tray                                                
3831              if (mAppsCustomizeTabHost != null) {                                                                  
3832                  mAppsCustomizeTabHost.trimMemory();                                                               
3833              }                                                                                                     

3834          }                                                                                                         
3835          if (mLauncherCallbacks != null) {                                                                         
3836              mLauncherCallbacks.onTrimMemory(level);                                                               
3837          }                                                                                                         
3838      }                                                                                                             
3839                                                                                                                    
3840      protected void showWorkspace(boolean animated) {                                                              
3841          showWorkspace(animated, null);                                                                            
3842      }                                                                                                             
3843                                                                                                                    
3844      protected void showWorkspace() {                                                                              
3845          showWorkspace(true);                                                                                      
3846      }                                                                                                             
3847                                                                                                                    
3848      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3849          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       



























3850              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3851              mWorkspace.setVisibility(View.VISIBLE);                                                               
3852              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 


3853                                                                                                                    
3854              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3855              // loaded mode)                                                                                       
3856              if (mSearchDropTargetBar != null) {                                                                   
3857                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3858              }                                                                                                     
3859                                                                                                                    
3860              // Set focus to the AppsCustomize button                                                              
3861              if (mAllAppsButton != null) {                                                                         
3862                  mAllAppsButton.requestFocus();                                                                    
3863              }                                                                                                     
3864          }                                                                                                         
3865                                                                                                                    
3866          // Change the state *after* we've called all the transition code                                          
3867          mState = State.WORKSPACE;                                                                                 
3868                                                                                                                    
3869          // Resume the auto-advance of widgets                                                                     
3870          mUserPresent = true;                                                                                      
3871          updateRunning();                                                                                          






















































































3872                                                                                                                    
3873          // Send an accessibility event to announce the context change                                             
3874          getWindow().getDecorView()                                                                                
3875                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3876                                                                                                                    
3877          onWorkspaceShown(animated);                                                                               
3878      }                                                                                                             
3879                                                                                                                    
3880      void showOverviewMode(boolean animated) {                                                                     
3881          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3882          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
3883          mState = State.WORKSPACE;                                                                                 
3884          onWorkspaceShown(animated);                                                                               
3885      }                                                                                                             
3886                                                                                                                    
3887      public void onWorkspaceShown(boolean animated) {                                                              
3888      }                                                                                                             
3889                                                                                                                    
3890      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
3891                       boolean resetPageToZero) {                                                                   
3892          if (mState != State.WORKSPACE) return;                                                                    
3893                                                                                                                    
3894          if (resetPageToZero) {                                                                                    
3895              mAppsCustomizeTabHost.reset();                                                                        
3896          }                                                                                                         
3897          showAppsCustomizeHelper(animated, false, contentType);                                                    
3898          mAppsCustomizeTabHost.post(new Runnable() {                                                               
3899              @Override                                                                                             
3900              public void run() {                                                                                   
3901                  // We post this in-case the all apps view isn't yet constructed.                                  
3902                  mAppsCustomizeTabHost.requestFocus();                                                             
3903              }                                                                                                     
3904          });                                                                                                       
3905                                                                                                                    
3906          // Change the state *after* we've called all the transition code                                          
3907          mState = State.APPS_CUSTOMIZE;                                                                            
3908                                                                                                                    
3909          // Pause the auto-advance of widgets until we are out of AllApps                                          
3910          mUserPresent = false;                                                                                     
3911          updateRunning();                                                                                          
3912          closeFolder();                                                                                            
3913                                                                                                                    
3914          // Send an accessibility event to announce the context change                                             
3915          getWindow().getDecorView()                                                                                
3916                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3917      }                                                                                                             
3918                                                                                                                    
3919      void enterSpringLoadedDragMode() {                                                                            
3920          if (isAllAppsVisible()) {                                                                                 
3921              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
3922              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
3923          }                                                                                                         
3924      }                                                                                                             
3925                                                                                                                    
3926      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 





























3927              final Runnable onCompleteRunnable) {                                                                  
3928          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 









3929                                                                                                                    
3930          mHandler.postDelayed(new Runnable() {                                                                     
3931              @Override                                                                                             
3932              public void run() {                                                                                   
3933                  if (successfulDrop) {                                                                             


3934                      // Before we show workspace, hide all apps again because                                      
3935                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
3936                      // clean up our state transition functions                                                    
3937                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               

3938                      showWorkspace(true, onCompleteRunnable);                                                      
3939                  } else {                                                                                          
3940                      exitSpringLoadedDragMode();                                                                   
3941                  }                                                                                                 
3942              }                                                                                                     
3943          }, delay);                                                                                                
3944      }                                                                                                             
3945                                                                                                                    
3946      void exitSpringLoadedDragMode() {                                                                             
3947          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
3948              final boolean animated = true;                                                                        
3949              final boolean springLoaded = true;                                                                    
3950              showAppsCustomizeHelper(animated, springLoaded);                                                      
3951              mState = State.APPS_CUSTOMIZE;                                                                        
3952          }                                                                                                         
3953          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     



















3954      }                                                                                                             
3955                                                                                                                    
3956      void lockAllApps() {                                                                                          
3957          // TODO                                                                                                   
3958      }                                                                                                             
3959                                                                                                                    
3960      void unlockAllApps() {                                                                                        
3961          // TODO                                                                                                   
3962      }                                                                                                             
3963                                                                                                                    
3964      protected void disableVoiceButtonProxy(boolean disable) {                                                     
3965          // NO-OP                                                                                                  
3966      }                                                                                                             
3967                                                                                                                    
3968      public View getQsbBar() {                                                                                     

3969          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
3970              return mLauncherCallbacks.getQsbBar();                                                                
3971          }                                                                                                         
3972                                                                                                                    
3973          if (mQsb == null) {                                                                                       
3974              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
3975              if (searchProvider == null) {                                                                         
3976                  return null;                                                                                      
3977              }                                                                                                     
3978                                                                                                                    
3979              Bundle opts = new Bundle();                                                                           
3980              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
3981                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
3982                                                                                                                    
3983              SharedPreferences sp = getSharedPreferences(                                                          
3984                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
3985              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
3986              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
3987              if (!searchProvider.provider.flattenToString().equals(                                                
3988                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
3989                      || (widgetInfo == null)                                                                       
3990                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
3991                  // A valid widget is not already bound.                                                           
3992                  if (widgetId > -1) {                                                                              
3993                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
3994                      widgetId = -1;                                                                                
3995                  }                                                                                                 
3996                                                                                                                    
3997                  // Try to bind a new widget                                                                       
3998                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
3999                                                                                                                    
4000                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
4001                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
4002                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4003                      widgetId = -1;                                                                                
4004                  }                                                                                                 
4005                                                                                                                    
4006                  sp.edit()                                                                                         
4007                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
4008                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
4009                      .commit();                                                                                    
4010              }                                                                                                     
4011                                                                                                                    
4012              if (widgetId != -1) {                                                                                 
4013                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
4014                  mQsb.updateAppWidgetOptions(opts);                                                                
4015                  mQsb.setPadding(0, 0, 0, 0);                                                                      
4016                  mSearchDropTargetBar.addView(mQsb);                                                               

4017              }                                                                                                     
4018          }                                                                                                         
4019          return mQsb;                                                                                              









4020      }                                                                                                             
4021                                                                                                                    
4022      @Override                                                                                                     
4023      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4024          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4025          final List<CharSequence> text = event.getText();                                                          
4026          text.clear();                                                                                             
4027          // Populate event with a fake title based on the current state.                                           
4028          if (mState == State.APPS_CUSTOMIZE) {                                                                     
4029              text.add(mAppsCustomizeTabHost.getContentTag());                                                      




4030          } else {                                                                                                  
4031              text.add(getString(R.string.all_apps_home_button_label));                                             
4032          }                                                                                                         
4033          return result;                                                                                            
4034      }                                                                                                             
4035                                                                                                                    
4036      /**                                                                                                           
4037       * Receives notifications when system dialogs are to be closed.                                               
4038       */                                                                                                           
4039      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    

4040          @Override                                                                                                 
4041          public void onReceive(Context context, Intent intent) {                                                   
4042              closeSystemDialogs();                                                                                 
4043          }                                                                                                         
4044      }                                                                                                             
4045                                                                                                                    
4046      /**                                                                                                           
4047       * Receives notifications whenever the appwidgets are reset.                                                  
4048       */                                                                                                           
4049      private class AppWidgetResetObserver extends ContentObserver {                                                
4050          public AppWidgetResetObserver() {                                                                         
4051              super(new Handler());                                                                                 
4052          }                                                                                                         
4053                                                                                                                    
4054          @Override                                                                                                 
4055          public void onChange(boolean selfChange) {                                                                
4056              onAppWidgetReset();                                                                                   
4057          }                                                                                                         
4058      }                                                                                                             
4059                                                                                                                    
4060      /**                                                                                                           
4061       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4062       * in onResume.                                                                                               
4063       *                                                                                                            
4064       * This needs to be called from incoming places where resources might have been loaded                        
4065       * while we are paused.  That is becaues the Configuration might be wrong                                     
4066       * when we're not running, and if it comes back to what it was when we                                        
4067       * were paused, we are not restarted.                                                                         



4068       *                                                                                                            
4069       * Implementation of the method from LauncherModel.Callbacks.                                                 
4070       *                                                                                                            
4071       * @return true if we are currently paused.  The caller might be able to                                      
4072       * skip some work in that case since we will come back again.                                                 

4073       */                                                                                                           
4074      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4075          if (mPaused) {                                                                                            
4076              Log.i(TAG, "Deferring update until onResume");                                                        

4077              if (deletePreviousRunnables) {                                                                        
4078                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4079                  }                                                                                                 
4080              }                                                                                                     
4081              mBindOnResumeCallbacks.add(run);                                                                      
4082              return true;                                                                                          
4083          } else {                                                                                                  
4084              return false;                                                                                         
4085          }                                                                                                         
4086      }                                                                                                             
4087                                                                                                                    
4088      private boolean waitUntilResume(Runnable run) {                                                               
4089          return waitUntilResume(run, false);                                                                       
4090      }                                                                                                             
4091                                                                                                                    
4092      public void addOnResumeCallback(Runnable run) {                                                               
4093          mOnResumeCallbacks.add(run);                                                                              
4094      }                                                                                                             
4095                                                                                                                    
4096      /**                                                                                                           
4097       * If the activity is currently paused, signal that we need to re-run the loader                              
4098       * in onResume.                                                                                               
4099       *                                                                                                            
4100       * This needs to be called from incoming places where resources might have been loaded                        
4101       * while we are paused.  That is becaues the Configuration might be wrong                                     
4102       * when we're not running, and if it comes back to what it was when we                                        
4103       * were paused, we are not restarted.                                                                         
4104       *                                                                                                            
4105       * Implementation of the method from LauncherModel.Callbacks.                                                 
4106       *                                                                                                            
4107       * @return true if we are currently paused.  The caller might be able to                                      
4108       * skip some work in that case since we will come back again.                                                 
4109       */                                                                                                           
4110      public boolean setLoadOnResume() {                                                                            
4111          if (mPaused) {                                                                                            
4112              Log.i(TAG, "setLoadOnResume");                                                                        

4113              mOnResumeNeedsLoad = true;                                                                            
4114              return true;                                                                                          
4115          } else {                                                                                                  
4116              return false;                                                                                         
4117          }                                                                                                         
4118      }                                                                                                             
4119                                                                                                                    
4120      /**                                                                                                           
4121       * Implementation of the method from LauncherModel.Callbacks.                                                 
4122       */                                                                                                           
4123      public int getCurrentWorkspaceScreen() {                                                                      
4124          if (mWorkspace != null) {                                                                                 
4125              return mWorkspace.getCurrentPage();                                                                   
4126          } else {                                                                                                  
4127              return SCREEN_COUNT / 2;                                                                              
4128          }                                                                                                         
4129      }                                                                                                             
4130                                                                                                                    
4131      /**                                                                                                           
4132       * Refreshes the shortcuts shown on the workspace.                                                            
4133       *                                                                                                            
4134       * Implementation of the method from LauncherModel.Callbacks.                                                 
4135       */                                                                                                           
4136      public void startBinding() {                                                                                  
4137          setWorkspaceLoading(true);                                                                                
4138                                                                                                                    
4139          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4140          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4141          // from scratch again                                                                                     
4142          mBindOnResumeCallbacks.clear();                                                                           
4143                                                                                                                    
4144          // Clear the workspace because it's going to be rebound                                                   
4145          mWorkspace.clearDropTargets();                                                                            
4146          mWorkspace.removeAllWorkspaceScreens();                                                                   
4147                                                                                                                    
4148          mWidgetsToAdvance.clear();                                                                                
4149          if (mHotseat != null) {                                                                                   
4150              mHotseat.resetLayout();                                                                               
4151          }                                                                                                         
4152      }                                                                                                             
4153                                                                                                                    
4154      @Override                                                                                                     
4155      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4156          bindAddScreens(orderedScreenIds);                                                                         
4157                                                                                                                    
4158          // If there are no screens, we need to have an empty screen                                               
4159          if (orderedScreenIds.size() == 0) {                                                                       
4160              mWorkspace.addExtraEmptyScreen();                                                                     
4161          }                                                                                                         
4162                                                                                                                    
4163          // Create the custom content page (this call updates mDefaultScreen which calls                           
4164          // setCurrentPage() so ensure that all pages are added before calling this).                              
4165          if (hasCustomContentToLeft()) {                                                                           
4166              mWorkspace.createCustomContentContainer();                                                            
4167              populateCustomContentContainer();                                                                     
4168          }                                                                                                         
4169      }                                                                                                             
4170                                                                                                                    
4171      @Override                                                                                                     
4172      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4173          // Log to disk                                                                                            
4174          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4175          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4176                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4177          int count = orderedScreenIds.size();                                                                      
4178          for (int i = 0; i < count; i++) {                                                                         
4179              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4180          }                                                                                                         
4181      }                                                                                                             
4182                                                                                                                    
4183      @Override                                                                                                     
4184      public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4185              final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4186          showWorkspace(true, new Runnable() {                                                                      
4187                                                                                                                    
4188              @Override                                                                                             
4189              public void run() {                                                                                   
4190                  mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4191                  addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4192              }                                                                                                     
4193          });                                                                                                       
4194      }                                                                                                             
4195                                                                                                                    
4196      private boolean shouldShowWeightWatcher() {                                                                   
4197          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4198          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4199          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4200                                                                                                                    
4201          return show;                                                                                              
4202      }                                                                                                             
4203                                                                                                                    
4204      private void toggleShowWeightWatcher() {                                                                      
4205          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4206          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4207          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4208                                                                                                                    
4209          show = !show;                                                                                             
4210                                                                                                                    
4211          SharedPreferences.Editor editor = sp.edit();                                                              
4212          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4213          editor.commit();                                                                                          
4214                                                                                                                    
4215          if (mWeightWatcher != null) {                                                                             
4216              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4217          }                                                                                                         
4218      }                                                                                                             
4219                                                                                                                    
4220      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4221                                final ArrayList<ItemInfo> addNotAnimated,                                           
4222                                final ArrayList<ItemInfo> addAnimated,                                              
4223                                final ArrayList<AppInfo> addedApps) {                                               
4224          Runnable r = new Runnable() {                                                                             
4225              public void run() {                                                                                   
4226                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4227              }                                                                                                     
4228          };                                                                                                        
4229          if (waitUntilResume(r)) {                                                                                 
4230              return;                                                                                               
4231          }                                                                                                         
4232                                                                                                                    
4233          // Add the new screens                                                                                    
4234          if (newScreens != null) {                                                                                 
4235              bindAddScreens(newScreens);                                                                           
4236          }                                                                                                         
4237                                                                                                                    
4238          // We add the items without animation on non-visible pages, and with                                      
4239          // animations on the new page (which we will try and snap to).                                            
4240          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4241              bindItems(addNotAnimated, 0,                                                                          
4242                      addNotAnimated.size(), false);                                                                
4243          }                                                                                                         
4244          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4245              bindItems(addAnimated, 0,                                                                             
4246                      addAnimated.size(), true);                                                                    
4247          }                                                                                                         
4248                                                                                                                    
4249          // Remove the extra empty screen                                                                          
4250          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4251                                                                                                                    
4252          if (!LauncherAppState.isDisableAllApps() &&                                                               
4253                  addedApps != null && mAppsCustomizeContent != null) {                                             
4254              mAppsCustomizeContent.addApps(addedApps);                                                             


4255          }                                                                                                         
4256      }                                                                                                             
4257                                                                                                                    
4258      /**                                                                                                           
4259       * Bind the items start-end from the list.                                                                    
4260       *                                                                                                            
4261       * Implementation of the method from LauncherModel.Callbacks.                                                 
4262       */                                                                                                           
4263      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4264                            final boolean forceAnimateIcons) {                                                      
4265          Runnable r = new Runnable() {                                                                             
4266              public void run() {                                                                                   
4267                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4268              }                                                                                                     
4269          };                                                                                                        
4270          if (waitUntilResume(r)) {                                                                                 
4271              return;                                                                                               
4272          }                                                                                                         
4273                                                                                                                    
4274          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4275          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4276          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4277          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4278          Workspace workspace = mWorkspace;                                                                         
4279          long newShortcutsScreenId = -1;                                                                           
4280          for (int i = start; i < end; i++) {                                                                       
4281              final ItemInfo item = shortcuts.get(i);                                                               
4282                                                                                                                    
4283              // Short circuit if we are loading dock items for a configuration which has no dock                   
4284              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4285                      mHotseat == null) {                                                                           
4286                  continue;                                                                                         
4287              }                                                                                                     
4288                                                                                                                    
4289              switch (item.itemType) {                                                                              
4290                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4291                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4292                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4293                      View shortcut = createShortcut(info);                                                         
4294                                                                                                                    
4295                      /*                                                                                            
4296                       * TODO: FIX collision case                                                                   
4297                       */                                                                                           
4298                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4299                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4300                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4301                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4302                              Object tag = v.getTag();                                                              
4303                              String desc = "Collision while binding workspace item: " + item                       
4304                                      + ". Collides with " + tag;                                                   
4305                              if (LauncherAppState.isDogfoodBuild()) {                                              
4306                                  throw (new RuntimeException(desc));                                               
4307                              } else {                                                                              
4308                                  Log.d(TAG, desc);                                                                 
4309                              }                                                                                     
4310                          }                                                                                         
4311                      }                                                                                             
4312                                                                                                                    
4313                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4314                              item.cellY, 1, 1);                                                                    
4315                      if (animateIcons) {                                                                           
4316                          // Animate all the applications up now                                                    
4317                          shortcut.setAlpha(0f);                                                                    
4318                          shortcut.setScaleX(0f);                                                                   
4319                          shortcut.setScaleY(0f);                                                                   
4320                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4321                          newShortcutsScreenId = item.screenId;                                                     
4322                      }                                                                                             
4323                      break;                                                                                        
4324                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4325                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4326                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4327                              (FolderInfo) item, mIconCache);                                                       
4328                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4329                              item.cellY, 1, 1);                                                                    
4330                      break;                                                                                        
4331                  default:                                                                                          
4332                      throw new RuntimeException("Invalid Item Type");                                              
4333              }                                                                                                     
4334          }                                                                                                         
4335                                                                                                                    
4336          if (animateIcons) {                                                                                       
4337              // Animate to the correct page                                                                        
4338              if (newShortcutsScreenId > -1) {                                                                      
4339                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4340                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4341                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4342                      public void run() {                                                                           
4343                          anim.playTogether(bounceAnims);                                                           
4344                          anim.start();                                                                             
4345                      }                                                                                             
4346                  };                                                                                                
4347                  if (newShortcutsScreenId != currentScreenId) {                                                    
4348                      // We post the animation slightly delayed to prevent slowdowns                                
4349                      // when we are loading right after we return to launcher.                                     
4350                      mWorkspace.postDelayed(new Runnable() {                                                       
4351                          public void run() {                                                                       
4352                              if (mWorkspace != null) {                                                             
4353                                  mWorkspace.snapToPage(newScreenIndex);                                            
4354                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4355                                          NEW_APPS_ANIMATION_DELAY);                                                
4356                              }                                                                                     
4357                          }                                                                                         
4358                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4359                  } else {                                                                                          
4360                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4361                  }                                                                                                 
4362              }                                                                                                     
4363          }                                                                                                         
4364          workspace.requestLayout();                                                                                
4365      }                                                                                                             
4366                                                                                                                    
4367      /**                                                                                                           
4368       * Implementation of the method from LauncherModel.Callbacks.                                                 
4369       */                                                                                                           
4370      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            

4371          Runnable r = new Runnable() {                                                                             
4372              public void run() {                                                                                   
4373                  bindFolders(folders);                                                                             
4374              }                                                                                                     
4375          };                                                                                                        
4376          if (waitUntilResume(r)) {                                                                                 
4377              return;                                                                                               
4378          }                                                                                                         
4379          sFolders.clear();                                                                                         
4380          sFolders.putAll(folders);                                                                                 

4381      }                                                                                                             
4382                                                                                                                    
4383      /**                                                                                                           
4384       * Add the views for a widget to the workspace.                                                               
4385       *                                                                                                            
4386       * Implementation of the method from LauncherModel.Callbacks.                                                 
4387       */                                                                                                           
4388      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4389          Runnable r = new Runnable() {                                                                             
4390              public void run() {                                                                                   
4391                  bindAppWidget(item);                                                                              
4392              }                                                                                                     
4393          };                                                                                                        
4394          if (waitUntilResume(r)) {                                                                                 
4395              return;                                                                                               
4396          }                                                                                                         
4397                                                                                                                    
4398          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4399          if (DEBUG_WIDGETS) {                                                                                      
4400              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4401          }                                                                                                         
4402          final Workspace workspace = mWorkspace;                                                                   
4403                                                                                                                    
4404          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4405                  LauncherModel.getProviderInfo(this, item.providerName, item.user);                                
4406                                                                                                                    
4407          if (!mIsSafeModeEnabled                                                                                   
4408                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4409                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4410              if (appWidgetInfo == null) {                                                                          
4411                  if (DEBUG_WIDGETS) {                                                                              
4412                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4413                              + " belongs to component " + item.providerName                                        
4414                              + ", as the povider is null");                                                        
4415                  }                                                                                                 
4416                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4417                  return;                                                                                           
4418              }                                                                                                     
4419              // Note: This assumes that the id remap broadcast is received before this step.                       
4420              // If that is not the case, the id remap will be ignored and user may see the                         
4421              // click to setup view.                                                                               
4422              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     

4423              pendingInfo.spanX = item.spanX;                                                                       
4424              pendingInfo.spanY = item.spanY;                                                                       
4425              pendingInfo.minSpanX = item.minSpanX;                                                                 
4426              pendingInfo.minSpanY = item.minSpanY;                                                                 
4427              Bundle options =                                                                                      
4428                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         


4429                                                                                                                    
4430              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4431              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4432                      newWidgetId, appWidgetInfo, options);                                                         
4433                                                                                                                    
4434              // TODO consider showing a permission dialog when the widget is clicked.                              
4435              if (!success) {                                                                                       
4436                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4437                  if (DEBUG_WIDGETS) {                                                                              
4438                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4439                              + " belongs to component " + item.providerName                                        
4440                              + ", as the launcher is unable to bing a new widget id");                             
4441                  }                                                                                                 
4442                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4443                  return;                                                                                           
4444              }                                                                                                     
4445                                                                                                                    
4446              item.appWidgetId = newWidgetId;                                                                       
4447                                                                                                                    
4448              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4449              // the widget is ready to go.                                                                         
4450              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4451                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4452                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4453                                                                                                                    
4454              LauncherModel.updateItemInDatabase(this, item);                                                       
4455          }                                                                                                         
4456                                                                                                                    
4457          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
4458              final int appWidgetId = item.appWidgetId;                                                             
4459              if (DEBUG_WIDGETS) {                                                                                  
4460                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
4461                          + appWidgetInfo.provider);                                                                
4462              }                                                                                                     
4463                                                                                                                    
4464              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4465          } else {                                                                                                  
4466              appWidgetInfo = null;                                                                                 
4467              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
4468                      mIsSafeModeEnabled);                                                                          
4469              view.updateIcon(mIconCache);                                                                          
4470              item.hostView = view;                                                                                 
4471              item.hostView.updateAppWidget(null);                                                                  
4472              item.hostView.setOnClickListener(this);                                                               
4473          }                                                                                                         
4474                                                                                                                    
4475          item.hostView.setTag(item);                                                                               
4476          item.onBindAppWidget(this);                                                                               
4477                                                                                                                    
4478          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4479                  item.cellY, item.spanX, item.spanY, false);                                                       
4480          if (!item.isCustomWidget()) {                                                                             
4481              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
4482          }                                                                                                         
4483                                                                                                                    
4484          workspace.requestLayout();                                                                                
4485                                                                                                                    
4486          if (DEBUG_WIDGETS) {                                                                                      
4487              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4488                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4489          }                                                                                                         
4490      }                                                                                                             
4491                                                                                                                    
4492      /**                                                                                                           
4493       * Restores a pending widget.                                                                                 
4494       *                                                                                                            
4495       * @param appWidgetId The app widget id                                                                       
4496       * @param cellInfo The position on screen where to create the widget.                                         
4497       */                                                                                                           
4498      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4499          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4500          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4501              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4502              return;                                                                                               
4503          }                                                                                                         
4504                                                                                                                    
4505          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4506          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4507                                                                                                                    
4508          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4509          LauncherModel.updateItemInDatabase(this, info);                                                           
4510      }                                                                                                             
4511                                                                                                                    
4512      public void onPageBoundSynchronously(int page) {                                                              
4513          mSynchronouslyBoundPages.add(page);                                                                       
4514      }                                                                                                             
4515                                                                                                                    
4516      /**                                                                                                           
4517       * Callback saying that there aren't any more items to bind.                                                  
4518       *                                                                                                            
4519       * Implementation of the method from LauncherModel.Callbacks.                                                 
4520       */                                                                                                           
4521      public void finishBindingItems(final boolean upgradePath) {                                                   

4522          Runnable r = new Runnable() {                                                                             
4523              public void run() {                                                                                   
4524                  finishBindingItems(upgradePath);                                                                  

4525              }                                                                                                     
4526          };                                                                                                        
4527          if (waitUntilResume(r)) {                                                                                 
4528              return;                                                                                               
4529          }                                                                                                         
4530          if (mSavedState != null) {                                                                                
4531              if (!mWorkspace.hasFocus()) {                                                                         
4532                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4533              }                                                                                                     
4534              mSavedState = null;                                                                                   
4535          }                                                                                                         
4536                                                                                                                    
4537          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4538                                                                                                                    
4539          setWorkspaceLoading(false);                                                                               
4540          sendLoadingCompleteBroadcastIfNecessary();                                                                
4541                                                                                                                    
4542          // If we received the result of any pending adds while the loader was running (e.g. the                   
4543          // widget configuration forced an orientation change), process them now.                                  
4544          if (sPendingAddItem != null) {                                                                            
4545              final long screenId = completeAdd(sPendingAddItem);                                                   
4546                                                                                                                    
4547              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4548              // the screen would be guaranteed to exist after bind, and the page would be set through              
4549              // the workspace restore process.                                                                     
4550              mWorkspace.post(new Runnable() {                                                                      
4551                  @Override                                                                                         
4552                  public void run() {                                                                               
4553                      mWorkspace.snapToScreenId(screenId);                                                          
4554                  }                                                                                                 
4555              });                                                                                                   
4556              sPendingAddItem = null;                                                                               
4557          }                                                                                                         
4558                                                                                                                    
4559          if (upgradePath) {                                                                                        
4560              mWorkspace.getUniqueComponents(true, null);                                                           
4561              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4562          }                                                                                                         
4563          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  

4564                                                                                                                    
4565          if (mLauncherCallbacks != null) {                                                                         
4566              mLauncherCallbacks.finishBindingItems(upgradePath);                                                   

4567          }                                                                                                         
4568      }                                                                                                             
4569                                                                                                                    
4570      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4571          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4572              String permission =                                                                                   
4573                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4574              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4575              sendBroadcast(intent, permission);                                                                    
4576              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4577              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4578              editor.apply();                                                                                       
4579          }                                                                                                         
4580      }                                                                                                             
4581                                                                                                                    
4582      public boolean isAllAppsButtonRank(int rank) {                                                                
4583          if (mHotseat != null) {                                                                                   
4584              return mHotseat.isAllAppsButtonRank(rank);                                                            
4585          }                                                                                                         
4586          return false;                                                                                             
4587      }                                                                                                             
4588                                                                                                                    
4589      private boolean canRunNewAppsAnimation() {                                                                    
4590          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4591          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4592      }                                                                                                             
4593                                                                                                                    
4594      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4595          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4596                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4597                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4598                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4599          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4600          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4601          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4602          return bounceAnim;                                                                                        
4603      }                                                                                                             
4604                                                                                                                    
4605      public boolean useVerticalBarLayout() {                                                                       
4606          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4607                  getDeviceProfile().isVerticalBarLayout();                                                         

4608      }                                                                                                             
4609                                                                                                                    
4610      protected Rect getSearchBarBounds() {                                                                         
4611          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4612                  getDeviceProfile().getSearchBarBounds();                                                          

4613      }                                                                                                             
4614                                                                                                                    
4615      public void bindSearchablesChanged() {                                                                        
4616          if (mSearchDropTargetBar == null) {                                                                       
4617              return;                                                                                               
4618          }                                                                                                         
4619          if (mQsb != null) {                                                                                       
4620              mSearchDropTargetBar.removeView(mQsb);                                                                
4621              mQsb = null;                                                                                          
4622          }                                                                                                         
4623          mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        
4624      }                                                                                                             














4625                                                                                                                    
4626      /**                                                                                                           
4627       * Add the icons for all apps.                                                                                
4628       *                                                                                                            
4629       * Implementation of the method from LauncherModel.Callbacks.                                                 
4630       */                                                                                                           
4631      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4632          if (LauncherAppState.isDisableAllApps()) {                                                                
4633              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4634                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4635                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4636                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4637                  }                                                                                                 
4638                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4639              }                                                                                                     
4640              if (mAppsCustomizeContent != null) {                                                                  
4641                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4642                          LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4643              }                                                                                                     
4644          } else {                                                                                                  
4645              if (mAppsCustomizeContent != null) {                                                                  
4646                  mAppsCustomizeContent.setApps(apps);                                                              
4647                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4648                          LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4649              }                                                                                                     







4650          }                                                                                                         
4651          if (mLauncherCallbacks != null) {                                                                         
4652              mLauncherCallbacks.bindAllApplications(apps);                                                         
4653          }                                                                                                         
4654      }                                                                                                             
4655                                                                                                                    
4656      /**                                                                                                           
4657       * A package was updated.                                                                                     
4658       *                                                                                                            
4659       * Implementation of the method from LauncherModel.Callbacks.                                                 
4660       */                                                                                                           
4661      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4662          Runnable r = new Runnable() {                                                                             
4663              public void run() {                                                                                   
4664                  bindAppsUpdated(apps);                                                                            
4665              }                                                                                                     
4666          };                                                                                                        
4667          if (waitUntilResume(r)) {                                                                                 
4668              return;                                                                                               
4669          }                                                                                                         
4670                                                                                                                    
4671          if (!LauncherAppState.isDisableAllApps() &&                                                               
4672                  mAppsCustomizeContent != null) {                                                                  
4673              mAppsCustomizeContent.updateApps(apps);                                                               


4674          }                                                                                                         
4675      }                                                                                                             
4676                                                                                                                    
4677      @Override                                                                                                     
4678      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
4679          Runnable r = new Runnable() {                                                                             
4680              public void run() {                                                                                   
4681                  bindWidgetsRestored(widgets);                                                                     
4682              }                                                                                                     
4683          };                                                                                                        
4684          if (waitUntilResume(r)) {                                                                                 
4685              return;                                                                                               
4686          }                                                                                                         
4687          mWorkspace.widgetsRestored(widgets);                                                                      
4688      }                                                                                                             
4689                                                                                                                    
4690      /**                                                                                                           
4691       * Some shortcuts were updated in the background.                                                             
4692       *                                                                                                            
4693       * Implementation of the method from LauncherModel.Callbacks.                                                 
4694       */                                                                                                           
4695      @Override                                                                                                     
4696      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
4697              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
4698          Runnable r = new Runnable() {                                                                             
4699              public void run() {                                                                                   
4700                  bindShortcutsChanged(updated, removed, user);                                                     
4701              }                                                                                                     
4702          };                                                                                                        
4703          if (waitUntilResume(r)) {                                                                                 
4704              return;                                                                                               
4705          }                                                                                                         
4706                                                                                                                    
4707          if (!updated.isEmpty()) {                                                                                 
4708              mWorkspace.updateShortcuts(updated);                                                                  
4709          }                                                                                                         
4710                                                                                                                    
4711          if (!removed.isEmpty()) {                                                                                 
4712              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4713              for (ShortcutInfo si : removed) {                                                                     
4714                  removedComponents.add(si.getTargetComponent());                                                   
4715              }                                                                                                     
4716              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
4717              // Notify the drag controller                                                                         
4718              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
4719          }                                                                                                         
4720      }                                                                                                             
4721                                                                                                                    
4722      /**                                                                                                           
4723       * Update the state of a package, typically related to install state.                                         
4724       *                                                                                                            
4725       * Implementation of the method from LauncherModel.Callbacks.                                                 
4726       */                                                                                                           
4727      @Override                                                                                                     
4728      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4729          if (mWorkspace != null) {                                                                                 
4730              mWorkspace.updatePackageState(installInfo);                                                           
4731          }                                                                                                         
4732      }                                                                                                             
4733                                                                                                                    
4734      /**                                                                                                           
4735       * Update the label and icon of all the icons in a package                                                    
4736       *                                                                                                            
4737       * Implementation of the method from LauncherModel.Callbacks.                                                 
4738       */                                                                                                           
4739      @Override                                                                                                     
4740      public void updatePackageBadge(String packageName) {                                                          
4741          if (mWorkspace != null) {                                                                                 
4742              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4743          }                                                                                                         











4744      }                                                                                                             
4745                                                                                                                    
4746      /**                                                                                                           
4747       * A package was uninstalled.  We take both the super set of packageNames                                     
4748       * in addition to specific applications to remove, the reason being that                                      
4749       * this can be called when a package is updated as well.  In that scenario,                                   
4750       * we only remove specific components from the workspace, where as                                            
4751       * package-removal should clear all items by package name.                                                    
4752       *                                                                                                            
4753       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
4754       * Implementation of the method from LauncherModel.Callbacks.                                                 
4755       */                                                                                                           
4756      @Override                                                                                                     
4757      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4758              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
4759          Runnable r = new Runnable() {                                                                             
4760              public void run() {                                                                                   
4761                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
4762              }                                                                                                     
4763          };                                                                                                        
4764          if (waitUntilResume(r)) {                                                                                 
4765              return;                                                                                               
4766          }                                                                                                         
4767                                                                                                                    
4768          if (reason == 0) {                                                                                        
4769              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4770              for (AppInfo info : appInfos) {                                                                       
4771                  removedComponents.add(info.componentName);                                                        
4772              }                                                                                                     
4773              if (!packageNames.isEmpty()) {                                                                        
4774                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
4775              }                                                                                                     
4776              if (!removedComponents.isEmpty()) {                                                                   
4777                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
4778              }                                                                                                     
4779              // Notify the drag controller                                                                         
4780              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
4781                                                                                                                    
4782          } else {                                                                                                  
4783              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
4784          }                                                                                                         
4785                                                                                                                    
4786          // Update AllApps                                                                                         
4787          if (!LauncherAppState.isDisableAllApps() &&                                                               
4788                  mAppsCustomizeContent != null) {                                                                  
4789              mAppsCustomizeContent.removeApps(appInfos);                                                           
4790          }                                                                                                         
4791      }                                                                                                             
4792                                                                                                                    
4793      /**                                                                                                           
4794       * A number of packages were updated.                                                                         
4795       */                                                                                                           
4796      private ArrayList<Object> mWidgetsAndShortcuts;                                                               





4797      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4798              public void run() {                                                                                   
4799                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4800                  mWidgetsAndShortcuts = null;                                                                      

4801              }                                                                                                     
4802          };                                                                                                        
4803      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                



4804          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4805              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           

4806              return;                                                                                               
4807          }                                                                                                         
4808                                                                                                                    
4809          // Update the widgets pane                                                                                
4810          if (mAppsCustomizeContent != null) {                                                                      
4811              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         



4812          }                                                                                                         
4813      }                                                                                                             
4814                                                                                                                    
4815      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4816          final Display d = getWindowManager().getDefaultDisplay();                                                 
4817          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4818          switch (d.getRotation()) {                                                                                
4819          case Surface.ROTATION_0:                                                                                  
4820          case Surface.ROTATION_180:                                                                                
4821              // We are currently in the same basic orientation as the natural orientation                          
4822              naturalOri = configOri;                                                                               
4823              break;                                                                                                
4824          case Surface.ROTATION_90:                                                                                 
4825          case Surface.ROTATION_270:                                                                                
4826              // We are currently in the other basic orientation to the natural orientation                         
4827              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
4828                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
4829              break;                                                                                                
4830          }                                                                                                         
4831                                                                                                                    
4832          int[] oriMap = {                                                                                          
4833                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
4834                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
4835                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
4836                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
4837          };                                                                                                        
4838          // Since the map starts at portrait, we need to offset if this device's natural orientation               
4839          // is landscape.                                                                                          
4840          int indexOffset = 0;                                                                                      
4841          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
4842              indexOffset = 1;                                                                                      
4843          }                                                                                                         
4844          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
4845      }                                                                                                             
4846                                                                                                                    
4847      public void lockScreenOrientation() {                                                                         
4848          if (Utilities.isRotationEnabled(this)) {                                                                  
4849              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
4850                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
4851                          .getConfiguration().orientation));                                                        
4852              } else {                                                                                              
4853                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
4854              }                                                                                                     
4855          }                                                                                                         
4856      }                                                                                                             
4857      public void unlockScreenOrientation(boolean immediate) {                                                      
4858          if (Utilities.isRotationEnabled(this)) {                                                                  
4859              if (immediate) {                                                                                      
4860                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
4861              } else {                                                                                              
4862                  mHandler.postDelayed(new Runnable() {                                                             
4863                      public void run() {                                                                           
4864                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
4865                      }                                                                                             
4866                  }, mRestoreScreenOrientationDelay);                                                               
4867              }                                                                                                     
4868          }                                                                                                         
4869      }                                                                                                             
4870                                                                                                                    
4871      protected boolean isLauncherPreinstalled() {                                                                  
4872          if (mLauncherCallbacks != null) {                                                                         
4873              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
4874          }                                                                                                         
4875          PackageManager pm = getPackageManager();                                                                  
4876          try {                                                                                                     
4877              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
4878              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
4879                  return true;                                                                                      
4880              } else {                                                                                              
4881                  return false;                                                                                     
4882              }                                                                                                     
4883          } catch (NameNotFoundException e) {                                                                       
4884              e.printStackTrace();                                                                                  
4885              return false;                                                                                         
4886          }                                                                                                         
4887      }                                                                                                             
4888                                                                                                                    
4889      /**                                                                                                           
4890       * This method indicates whether or not we should suggest default wallpaper dimensions                        
4891       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
4892       */                                                                                                           
4893      protected boolean overrideWallpaperDimensions() {                                                             
4894          if (mLauncherCallbacks != null) {                                                                         
4895              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
4896          }                                                                                                         
4897          return true;                                                                                              
4898      }                                                                                                             
4899                                                                                                                    
4900      /**                                                                                                           
4901       * To be overridden by subclasses to indicate that there is an activity to launch                             
4902       * before showing the standard launcher experience.                                                           
4903       */                                                                                                           
4904      protected boolean hasFirstRunActivity() {                                                                     
4905          if (mLauncherCallbacks != null) {                                                                         
4906              return mLauncherCallbacks.hasFirstRunActivity();                                                      
4907          }                                                                                                         
4908          return false;                                                                                             
4909      }                                                                                                             
4910                                                                                                                    
4911      /**                                                                                                           
4912       * To be overridden by subclasses to launch any first run activity                                            
4913       */                                                                                                           
4914      protected Intent getFirstRunActivity() {                                                                      
4915          if (mLauncherCallbacks != null) {                                                                         
4916              return mLauncherCallbacks.getFirstRunActivity();                                                      
4917          }                                                                                                         
4918          return null;                                                                                              














4919      }                                                                                                             
4920                                                                                                                    
4921      private boolean shouldRunFirstRunActivity() {                                                                 
4922          return !ActivityManager.isRunningInTestHarness() &&                                                       
4923                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
4924      }                                                                                                             
4925                                                                                                                    
4926      protected boolean hasRunFirstRunActivity() {                                                                  
4927          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
4928      }                                                                                                             
4929                                                                                                                    
4930      public boolean showFirstRunActivity() {                                                                       
4931          if (shouldRunFirstRunActivity() &&                                                                        
4932                  hasFirstRunActivity()) {                                                                          
4933              Intent firstRunIntent = getFirstRunActivity();                                                        
4934              if (firstRunIntent != null) {                                                                         
4935                  startActivity(firstRunIntent);                                                                    
4936                  markFirstRunActivityShown();                                                                      
4937                  return true;                                                                                      
4938              }                                                                                                     
4939          }                                                                                                         
4940          return false;                                                                                             
4941      }                                                                                                             
4942                                                                                                                    
4943      private void markFirstRunActivityShown() {                                                                    
4944          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
4945          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
4946          editor.apply();                                                                                           
4947      }                                                                                                             
4948                                                                                                                    
4949      /**                                                                                                           
4950       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
4951       * screen that must be displayed and dismissed.                                                               
4952       */                                                                                                           
4953      protected boolean hasDismissableIntroScreen() {                                                               
4954          if (mLauncherCallbacks != null) {                                                                         
4955              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
4956          }                                                                                                         
4957          return false;                                                                                             
4958      }                                                                                                             
4959                                                                                                                    
4960      /**                                                                                                           
4961       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
4962       */                                                                                                           
4963      protected View getIntroScreen() {                                                                             
4964          if (mLauncherCallbacks != null) {                                                                         
4965              return mLauncherCallbacks.getIntroScreen();                                                           
4966          }                                                                                                         
4967          return null;                                                                                              
4968      }                                                                                                             
4969                                                                                                                    
4970      /**                                                                                                           
4971       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
4972       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
4973       */                                                                                                           
4974      private boolean shouldShowIntroScreen() {                                                                     
4975          return hasDismissableIntroScreen() &&                                                                     
4976                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
4977      }                                                                                                             
4978                                                                                                                    
4979      protected void showIntroScreen() {                                                                            
4980          View introScreen = getIntroScreen();                                                                      
4981          changeWallpaperVisiblity(false);                                                                          
4982          if (introScreen != null) {                                                                                
4983              mDragLayer.showOverlayView(introScreen);                                                              
4984          }                                                                                                         
4985          if (mLauncherOverlayContainer != null) {                                                                  
4986              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
4987          }                                                                                                         
4988      }                                                                                                             
4989                                                                                                                    
4990      public void dismissIntroScreen() {                                                                            
4991          markIntroScreenDismissed();                                                                               
4992          if (showFirstRunActivity()) {                                                                             
4993              // We delay hiding the intro view until the first run activity is showing. This                       
4994              // avoids a blip.                                                                                     
4995              mWorkspace.postDelayed(new Runnable() {                                                               
4996                  @Override                                                                                         
4997                  public void run() {                                                                               
4998                      mDragLayer.dismissOverlayView();                                                              
4999                      if (mLauncherOverlayContainer != null) {                                                      
5000                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
5001                      }                                                                                             
5002                      showFirstRunClings();                                                                         
5003                  }                                                                                                 
5004              }, ACTIVITY_START_DELAY);                                                                             
5005          } else {                                                                                                  
5006              mDragLayer.dismissOverlayView();                                                                      
5007              if (mLauncherOverlayContainer != null) {                                                              
5008                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
5009              }                                                                                                     
5010              showFirstRunClings();                                                                                 
5011          }                                                                                                         
5012          changeWallpaperVisiblity(true);                                                                           
5013      }                                                                                                             
5014                                                                                                                    
5015      private void markIntroScreenDismissed() {                                                                     
5016          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5017          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5018          editor.apply();                                                                                           
5019      }                                                                                                             
5020                                                                                                                    
5021      private void showFirstRunClings() {                                                                           

5022          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5023          // on the device, then we always show the first run cling experience (or if there is no                   
5024          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5025          LauncherClings launcherClings = new LauncherClings(this);                                                 
5026          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5027              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5028                  launcherClings.showMigrationCling();                                                              
5029              } else {                                                                                              
5030                  launcherClings.showLongPressCling(true);                                                          
5031              }                                                                                                     
5032          }                                                                                                         
5033      }                                                                                                             
5034                                                                                                                    
5035      void showWorkspaceSearchAndHotseat() {                                                                        
5036          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5037          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5038          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5039          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5040      }                                                                                                             
5041                                                                                                                    
5042      void hideWorkspaceSearchAndHotseat() {                                                                        
5043          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5044          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5045          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5046          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5047      }                                                                                                             
5048                                                                                                                    
5049      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5050          // Called from search suggestion, not supported in other profiles.                                        
5051          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5052          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5053          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5054                  myUser);                                                                                          
5055          if (activityInfo == null) {                                                                               
5056              return null;                                                                                          
5057          }                                                                                                         
5058          return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         

5059      }                                                                                                             
5060                                                                                                                    
5061      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5062              Bitmap icon) {                                                                                        
5063          // Called from search suggestion, not supported in other profiles.                                        
5064          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5065                  UserHandleCompat.myUserHandle());                                                                 
5066      }                                                                                                             
5067                                                                                                                    
5068      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5069              Bitmap icon, UserHandleCompat user) {                                                                 
5070          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5071          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5072          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5073      }                                                                                                             
5074                                                                                                                    
5075      protected void moveWorkspaceToDefaultScreen() {                                                               
5076          mWorkspace.moveToDefaultScreen(false);                                                                    
5077      }                                                                                                             
5078                                                                                                                    
5079      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5080          dragView.setTag(dragInfo);                                                                                
5081          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5082          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5083      }                                                                                                             
5084                                                                                                                    
5085      @Override                                                                                                     
5086      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5087          if (mLauncherCallbacks != null) {                                                                         
5088              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5089          }                                                                                                         
5090      }                                                                                                             
5091                                                                                                                    
5092      /**                                                                                                           
5093       * Prints out out state for debugging.                                                                        
5094       */                                                                                                           
5095      public void dumpState() {                                                                                     
5096          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5097          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5098          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5099          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5100          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5101          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5102          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5103          mModel.dumpState();                                                                                       
5104                                                                                                                    
5105          if (mAppsCustomizeContent != null) {                                                                      
5106              mAppsCustomizeContent.dumpState();                                                                    
5107          }                                                                                                         


5108          Log.d(TAG, "END launcher3 dump state");                                                                   
5109      }                                                                                                             
5110                                                                                                                    
5111      @Override                                                                                                     
5112      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5113          super.dump(prefix, fd, writer, args);                                                                     
5114          synchronized (sDumpLogs) {                                                                                
5115              writer.println(" ");                                                                                  
5116              writer.println("Debug logs: ");                                                                       
5117              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5118                  writer.println("  " + sDumpLogs.get(i));                                                          
5119              }                                                                                                     
5120          }                                                                                                         
5121          if (mLauncherCallbacks != null) {                                                                         
5122              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5123          }                                                                                                         
5124      }                                                                                                             
5125                                                                                                                    
5126      public static void dumpDebugLogsToConsole() {                                                                 
5127          if (DEBUG_DUMP_LOG) {                                                                                     
5128              synchronized (sDumpLogs) {                                                                            
5129                  Log.d(TAG, "");                                                                                   
5130                  Log.d(TAG, "*********************");                                                              
5131                  Log.d(TAG, "Launcher debug logs: ");                                                              
5132                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5133                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5134                  }                                                                                                 
5135                  Log.d(TAG, "*********************");                                                              
5136                  Log.d(TAG, "");                                                                                   
5137              }                                                                                                     
5138          }                                                                                                         
5139      }                                                                                                             
5140                                                                                                                    
5141      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5142          addDumpLog(tag, log, null, debugLog);                                                                     
5143      }                                                                                                             
5144                                                                                                                    
5145      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5146          if (debugLog) {                                                                                           
5147              if (e != null) {                                                                                      
5148                  Log.d(tag, log, e);                                                                               
5149              } else {                                                                                              
5150                  Log.d(tag, log);                                                                                  
5151              }                                                                                                     
5152          }                                                                                                         
5153          if (DEBUG_DUMP_LOG) {                                                                                     
5154              sDateStamp.setTime(System.currentTimeMillis());                                                       
5155              synchronized (sDumpLogs) {                                                                            
5156                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5157                      + (e == null ? "" : (", Exception: " + e)));                                                  
5158              }                                                                                                     
5159          }                                                                                                         
5160      }                                                                                                             
5161                                                                                                                    
5162      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5163          return sCustomAppWidgets.get(name);                                                                       
5164      }                                                                                                             
5165                                                                                                                    
5166      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5167          return sCustomAppWidgets;                                                                                 
5168      }                                                                                                             
5169                                                                                                                    
5170      public void dumpLogsToLocalData() {                                                                           
5171          if (DEBUG_DUMP_LOG) {                                                                                     
5172              new AsyncTask<Void, Void, Void>() {                                                                   
5173                  public Void doInBackground(Void ... args) {                                                       
5174                      boolean success = false;                                                                      
5175                      sDateStamp.setTime(sRunStart);                                                                
5176                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5177                              + sDateStamp.getDay() + "_"                                                           
5178                              + sDateStamp.getHours() + "-"                                                         
5179                              + sDateStamp.getMinutes() + "_"                                                       
5180                              + sDateStamp.getSeconds() + ".txt";                                                   
5181                                                                                                                    
5182                      FileOutputStream fos = null;                                                                  
5183                      File outFile = null;                                                                          
5184                      try {                                                                                         
5185                          outFile = new File(getFilesDir(), FILENAME);                                              
5186                          outFile.createNewFile();                                                                  
5187                          fos = new FileOutputStream(outFile);                                                      
5188                      } catch (Exception e) {                                                                       
5189                          e.printStackTrace();                                                                      
5190                      }                                                                                             
5191                      if (fos != null) {                                                                            
5192                          PrintWriter writer = new PrintWriter(fos);                                                
5193                                                                                                                    
5194                          writer.println(" ");                                                                      
5195                          writer.println("Debug logs: ");                                                           
5196                          synchronized (sDumpLogs) {                                                                
5197                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5198                                  writer.println("  " + sDumpLogs.get(i));                                          
5199                              }                                                                                     
5200                          }                                                                                         
5201                          writer.close();                                                                           
5202                      }                                                                                             
5203                      try {                                                                                         
5204                          if (fos != null) {                                                                        
5205                              fos.close();                                                                          
5206                              success = true;                                                                       
5207                          }                                                                                         
5208                      } catch (IOException e) {                                                                     
5209                          e.printStackTrace();                                                                      
5210                      }                                                                                             
5211                      return null;                                                                                  
5212                  }                                                                                                 
5213              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5214          }                                                                                                         
5215      }                                                                                                             
5216  }                                                                                                                 
5217                                                                                                                    
5218  interface LauncherTransitionable {                                                                                
5219      View getContent();                                                                                            
5220      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5221      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5222      void onLauncherTransitionStep(Launcher l, float t);                                                           
5223      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5224  }                                                                                                                 
5225                                                                                                                    
5226  interface DebugIntents {                                                                                          
5227      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5228      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5229  }